1、面向对象的三个基本特征?
封装:隐藏对象实现细节,对外访问只暴露接口
继承:让一个类型获得另外一个属性及方法
多态:对于同一个父类所定义的行为,不同子类有着不同的实现
存在条件:1)首先子类继承父类 2)子类重写父类的方法 3)父类引用子类对象
2、访问修饰符public,private,protected,以及不写时的区别?
public 支持所有访问
protected 不支持其他包的访问
default 不支持子类访问
private 不支持其他类的访问
3、下面两个代码块能正常编译和执行吗?
// 代码块1
short s1 = 1; s1 = s1 + 1;
// 代码块2
short s1 = 1; s1 += 1;
代码块1编译报错:不兼容类型问题 - int 转 short 会有缺失
代码块2正常:通过编译后的字节码可以看出其中包含了 i2s 指令即 int to short
其中 s1 += 1 === s1 = (short)(s1 + 1);
4、基础考察,指出下题的输出结果
public static void main(String[] args) {
Integer a = 128, b = 128, c = 127, d = 127;
System.out.println(a == b);
System.out.println(c == d);
}
false true
其中 Integer a = 128 === Integer a = Integer.valueOf(128) 基本数据类型通过自动装箱成包装类引用类型
在 Integer 中引入了 IntegerCache 常量池来缓存一定默认范围的值(-128~127)
当然可以通过xx:AutoBoxCacheMax=进行修改
5、用最有效率的方法计算2乘以8?
2 << 3
6、&和&&的区别?
&& 具有短路性 & 不具有短路性 适合位运算
7、String 是 Java 基本数据类型吗?
他是一个final不可继承的类
基本数据类型存放在 栈 上
而引用数据类型存放在 堆 上
8、String 类可以继承吗?
不行。String 类使用 final 修饰,无法被继承。
9、String和StringBuilder、StringBuffer的区别?
String:创建后不能改变,如果改变则会创建新的对象
StringBuilder:其值可以改变,但要使用 synchronized 来保证线程安全
StringBuffer: 其值一样可以改变,StringBuilder的非线程安全版本,但具有较高的性能,推荐使用
10、String s = new String(“xyz”) 创建了几个字符串对象?
一个或者两个。
如果此时字符串常量池当中没有“xyz”的话,则会创建两个对象:
- 一个是驻留在字符串常量池中存放引用,实例放在堆中
- 另一个通过 new String() 创建并初始化,内容与"xyz"相同的实例放在堆中
11、String s = “xyz” 和 String s = new String(“xyz”) 区别?
两个语句都会先去字符串常量池当中查找是否有"xyz",如果有则直接使用。
否则,就会在常量池当中创建"xyz"
另外 new String() 会再创建一个相同的对象在堆中
后者包含前者。
12、== 和 equals 的区别是什么?
== :
对于基本数据类型:
只会比较两者的 值 是否相同,不考虑两者类型
short s1 = 1; long l1 = 1;
// 结果:true。类型不同,但是值相同
System.out.println(s1 == l1);
对于引用数据类型:
会比较两者的地址是否相同
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
// 结果:false。通过new创建,在内存中指向两个不同的对象
System.out.println(i1 == i2);
equals()方法:
Object 中的方法,通常重写为比较两对象中的值是否相同
但如果不重写Object中的原方法,则仍然只会比较两对象的地址是否相同
Integer i1 = new Integer(1);
Integer i2 = new Integer(1);
// 结果:true。两个不同的对象,但是具有相同的值
System.out.println(i1.equals(i2));
// Integer的equals重写方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
// 比较对象中保存的值是否相同
return value == ((Integer)obj).intValue();
}
return false;
}
13、两个对象的 hashCode() 相同,则 equals() 也一定为 true,对吗?
不对。
当 a.equals(b) == true 时,a.hashCode() == b.hashCode()
但如果 a.hashCode() == b.hashCode() 时,a.equals(b) 不等于 true
14、什么是反射
是指运行状态下,任意一个类处于一个上帝视角,可以访问到任意想要访问的任意类中的成员属性和方法,
并且对于任意一个对象,都能调用他的任意一个方法,
这种动态的获取信息,及动态调用对象方法的功能称为反射机制,一般在框架源码涉及到。
15、深拷贝和浅拷贝区别是什么?
浅拷贝:
对于基本数据类型:只是复制数据值;
对于引用数据类型:只是复制对象的引用地址,因此新旧对象指向的同一内存地址,修改其中一个对象,内外一个对象也会相应改变
深拷贝:
对于基本数据类型:还只是复制数据值;
对于引用数据类型:就会开辟一个新的内存空间,在新的内存空间里复制一个完全一样的对象
当然深拷贝比浅拷贝速度较慢,开销较大
16、并发和并行有什么区别?
并发:两个或多个事件在同一时间间隔发生。
并行:两个或者多个事件在同一时刻发生。
17、构造器是否可被 重写?
Constructor 不能被重新(override)但可以重载(reload)
18、当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?
值传递。Java 中只有值传递,对于对象参数,值的内容是对象的引用。
19、Java 静态变量和成员变量的区别
成员变量属于对象为实例变量,静态变量属性类为类变量
存放位置不同:
静态变量存放在方法区当中,成员变量存放在堆内存中
共存亡对象不同:
成员变量与对象共存亡,而静态变量与类共存亡
20、是否可以从一个静态(static)方法内部发出对非静态(non-static)方法的调用?
要看是否创建对象。
21、初始化考察,请指出下面程序的运行结果。
public class InitialTest {
public static void main(String[] args) {
A ab = new B();
ab = new B();
}
}
class A {
static { // 父类静态代码块
System.out.print("A");
}
public A() { // 父类构造器
System.out.print("a");
}
}
class B extends A {
static { // 子类静态代码块
System.out.print("B");
}
public B() { // 子类构造器
System.out.print("b");
}
}
执行结果:ABabab
静态变量只会执行一次。
执行顺序:父静(变量,代码块) -> 子静 -> 父非静(变量,代码块) -> 父构 -> 子非静 -> 子构
22、重载(Overload)和重写(Override)的区别?
这两者都是实现多态的方式
前者为编译时的多态性,后者为运行时的多态性。
重载:同名,不同参数列表
重写:子类对父类的方法进行改造,参数不能改变,返回类型可以不同,但必须是父类返回值的派生类
23、为什么不能根据返回类型来区分重载?
// 方法1
int test(int a);
// 方法2
long test(int a);
方法返回值只是作为方法的一个"状态",不能以此区分。
24、抽象类(abstract class)和接口(interface)有什么区别?
抽象类:单继承|构造|成员变量 接口:多实现|无构造|静态成员变量
抽象类含有非抽象方法。
对于接口:
jdk 7之前:所有方法只能都是抽象
jdk 8之后:支持非抽象方法(default,static)
jdk 9:支持私有方法,静态方法
接口是自顶向下的思想,接口定义抽象了行为,而怎么具体实现,完全由自己决定去实现。
而抽象是自底向上的思想,提供了通用实现,剩下的可以自定义实现。
25、Error 和 Exception 有什么区别?
两者都是Throwable的子类。
Error表示系统级的错误,程序无需去处理
而Exception是程序当中能够捕捉到或需要程序进行下一步处理的异常
26、Java 中的 final 关键字有哪些用法?
修饰类:不能派生出新的子类,不能作为父类的继承
修饰方法:该方法不能够被子类进行重写
修饰变量:该变量必须定义出初值,以后只能读取,不可修改;如果变量是对象的话,引用无法修改,但其中的成员变量可以进行修改
27、阐述 final、finally、finalize 的区别
finally:是Java异常处理机制的最佳补充,搭配trycatch使用,无论是否出现异常都会执行相应代码
在实际的开发当中,通常用于释放锁、数据库连接等资源
finalize:已弃用。在jdk9引入Cleaner来更灵活和有效的方法进行释放资源。
28、try、catch、finally 考察,请指出下面程序的运行结果
public class TryDemo {
public static void main(String[] args) {
System.out.println(test());
}
public static int test() {
try {
return 1;
} catch (Exception e) {
return 2;
} finally {
System.out.print("3");
}
}
}
结果: 31
29、try、catch、finally 考察2,请指出下面程序的运行结果。
public class TryDemo {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
try {
return 2;
} finally {
return 3;
}
}
}
结果:3
30、try、catch、finally 考察3,请指出下面程序的运行结果
public class TryDemo {
public static void main(String[] args) {
System.out.println(test1());
}
public static int test1() {
int i = 0;
try {
i = 2;
return i;
} finally {
i = 3;
}
}
}
结果:2
底层原理:JVM在执行finally之前,先将i的值暂存下来,然后finally执行完毕之后,结果仍然返回原先暂存的i