JAVA基础面试题集合

1. instanceof 关键字的作用(了解)

instanceof 严格来说是Java中的一个双目运算符,类似于 ==,>,< 等操作符,用来测试一个对象是否为一个类的实例,用法
为:

boolean result = obj instanceof Class

其中 obj 为一个对象, Class 表示一个类或者一个接口,当 obj Class 的对象,或者是其直接
或间接子类,或者是其接口的实现类,结果 result 都返回 true ,否则返回 false
注意:编译器会检查 obj 是否能转换成右边的 class 类型,如果不能转换则直接报错,如果不能
确定类型,则通过编译,具体看运行时定。
int i = 0 ;
System . out . println ( i instanceof Integer ); // 编译不通过 i 必须是引用类型,不能是基本类型
System . out . println ( i instanceof Object ); // 编译不通过
Integer integer = new Integer ( 1 );
System . out . println ( integer instanceof Integer ); //true
//false , JavaSE 规范 中对 instanceof 运算符的规定就是:如果 obj null ,那么将返
false
System . out . println ( null instanceof Object );

2. Java自动装箱和拆箱

装箱就是自动将基本数据类型转换为包装器类型( int-->Integer );调用方法: Integer
valueOf(int) 方法,静态方法
Integer.valueOf(100);
拆箱就是自动将包装器类型转换为基本数据类型( Integer-->int )。调用方法: Integer
intValue 方法
Integer a=1;
int i = a.intValue();
而在从 Java SE5 开始就提供了自动装箱的特性,如果要生成一个数值为 10 Integer 对象,只需要
这样就可以了:
Integer i = 10;

面试题1: 以下代码会输出什么?

public class Main {
public static void main ( String [] args ) {
Integer i1 = 100 ;
Integer i2 = 100 ;
Integer i3 = 200 ;
Integer i4 = 200 ;
System . out . println ( i1 == i2 );
System . out . println ( i3 == i4 );
        }
}

 运行结果:

true

false

下面这段代码是Integer的valueOf方法的具体实现: cache[0]= -128     cache[128]=0

public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}

总结:Byte,Short,Integer,Long,Character。这5种整型的包装类的常量池范围在-128~127之间,也就是说, 超出这个范围的对象都会开辟自己的堆内存。 使用常量池的好处,不用频繁的去new对象,减少空间。

3. Java 创建对象有几种方式?

 3.1 使用 new 关键字,这也是我们平时使用的最多的创建对象的方式,示例:

User user = new User();

3.2 使用反射方式创建对象,使用 newInstance() 

User user=User.class.newInstance();
Object object=(Object)Class.forName("java.lang.Object").newInstance();

3.3 使用 clone 方法, clone 是 Object 的方法,所以所有对象都有这个方法。 

3.4 使用反序列化创建对象,调用 ObjectInputStream 类的 readObject() 方法。  

我们反序列化一个对象, JVM 会给我们创建一个单独的对象。 JVM 创建对象并不会调用任何构造函
数。一个对象实现了 Serializable 接口,就可以把对象写入到文件中,并通过读取文件来创建对
象。
总结
创建对象的方式关键字: new 、反射、 clone 拷贝、反序列化。

 4.Object 有哪些常用方法?大致说一下每个方法的含义

java.lang.Object
下面是对应方法的含义。
clone 方法
保护方法,实现对象的浅复制,只有实现了 Cloneable 接口才可以调用该方法,否则抛出
CloneNotSupportedException 异常,深拷贝也需要实现 Cloneable ,同时其成员变量为引用类型
的也需要实现 Cloneable ,然后重写 clone 方法。
public class Test implements Cloneable{
    public static void main(String[] args) throws CloneNotSupportedException {
        Test test = new Test();
        Object clone2 = test.clone();
        System.out.println(test==clone2);
    }
}
运行结果:false
finalize 方法

该方法和垃圾收集器有关系,一个对象的finalize()方法只会被调用一次

调用finalize() 方法的时机: 当JVM 确定不再有指向该对象的引用时,垃圾收集器在对象上调用该方法。
finalize() 方法的作用: JVM 调用该方法,表示该对象即将“死亡”,之后JVM就可以回收该对象了。有点类似对象生命周期的临终方法。

equals 方法
该方法使用频率非常高。一般 equals == 是不一样的,但是在 Object 中两者是一样的。子类一
般都要重写这个方法。
hashCode 方法
该方法用于哈希查找,重写了 equals 方法一般都要重写 hashCode 方法,这个方法在一些具有哈
希功能的 Collection 中用到。
一般必须满足 obj1.equals(obj2)==true 。可以推出 obj1.hashCode()==obj2.hashCode() ,但是
hashCode 相等不一定就满足 equals 。不过为了提高效率,应该尽量使上面两个条件接近等价。
JDK 1.6 1.7 默认是返回随机数;
JDK 1.8 默认是通过和当前线程有关的一个随机数 + 三个确定值,运用 Marsaglia’s xorshift
scheme 随机数算法得到的一个随机数。
wait 方法
配合 synchronized 使用, wait 方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥
有者,也就是具有该对象的锁。 wait() 方法一直等待,直到获得锁或者被中断。 wait(long timeout)
设定一个超时间隔,如果在规定时间内没有获得锁就返回。
调用该方法后当前线程进入睡眠状态,直到以下事件发生。
1. 其他线程调用了该对象的 notify 方法;
2. 其他线程调用了该对象的 notifyAll 方法;
3. 其他线程调用了 interrupt 中断该线程;
4. 时间间隔到了。
此时该线程就可以被调度了,如果是被中断的话就抛出一个 InterruptedException 异常。

notify 方法
配合 synchronized 使用,该方法唤醒在该对象上 等待队列 中的某个线程(同步队列中的线程是给
抢占 CPU 的线程,等待队列中的线程指的是等待唤醒的线程)。
notifyAll 方法
配合 synchronized 使用,该方法唤醒在该对象上等待队列中的所有线程。
总结
只要把上面几个方法熟悉就可以了, toString getClass 方法可以不用去讨论它们。该题目考察的
是对 Object 的熟悉程度,平时用的很多方法并没看其定义但是也在用,比如说: wait() 方法,
equals() 方法等。
Class Object is the root of the class hierarchy.Every class has Object as a
superclass. All objects, including arrays, implement the methods of this class.

 大致意思:Object 是所有类的根,是所有类的父类,所有对象包括数组都实现了 Object 的方法。

5. wait()和sleep()的区别

sleep()是使线程暂停执行一段时间的方法。wait()也是一种使线程暂停执行的方法。例如,当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。并且可以调用notify()方法或者notifyAll()方法通知正在等待的其他线程。notify()方法仅唤醒一个线程(等待队列中的第一个线程)并允许他去获得锁。notifyAll()方法唤醒所有等待这个对象的线程并允许他们去竞争获得锁。具体区别如下:

1)  原理不同。sleep()方法是Thread类的静态方法,是线程用来控制自身流程的,他会使此线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,此线程会自动苏醒。例如,当线程执行报时功能时,每一秒钟打印出一个时间,那么此时就需要在打印方法前面加一个sleep()方法,以便让自己每隔一秒执行一次,该过程如同闹钟一样。而wait()方法是object类的方法,用于线程间通信,这个方法会使当前拥有该对象锁的进程等待,直到其他线程调用notify()方法或者notifyAll()时才醒来,不过开发人员也可以给他指定一个时间,自动醒来。

2)  对锁的 处理机制不同。由于sleep()方法的主要作用是让线程暂停执行一段时间,时间一到则自动恢复,不涉及线程间的通信,因此,调用sleep()方法并不会释放锁。而wait()方法则不同,当调用wait()方法后,线程会释放掉他所占用的锁,从而使线程所在对象中的其他synchronized数据可以被其他线程使用。

3)  使用区域不同。wait()方法必须放在同步控制方法和同步代码块中使用,sleep()方法则可以放在任何地方使用。sleep()方法必须捕获异常,而wait()、notify()、notifyAll()不需要捕获异常。在sleep的过程中,有可能被其他对象调用他的interrupt(),产生InterruptedException。由于sleep不会释放锁标志,容易导致死锁问题的发生,因此一般情况下,推荐使用wait()方法。

6. final、finally与finalize三者的区别

6. 说说深拷贝和浅拷贝?

浅拷贝( shallowCopy )只是增加了一个指针指向已存在的内存地址,
深拷贝( deepCopy )是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新
的内存,
使用深拷贝的情况下,释放内存的时候不会因为出现浅拷贝时释放同一个内存的错误。
最好是结合克隆已经原型模式联系在一起哈,记得复习的时候,把这几个联系起来的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值