1.面向对象的三大特征
封装、继承、多态,也可加上抽象
2.多态的作用
允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)
可替换性:多态对于已存在的代码具有可替换性;
可扩充性:增加新的子类不影响已经存在的类结构;
接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类完善或者重写它来实现。
3.代码中如何实现多态
实现多态主要有一下三种方式:
接口实现
继承父类重写方法
同一类中进行方法重载
4.虚拟机是如何实现多态的
动态绑定技术(dynspanmic binding),执行期间判断所引用对象的实际类型,根据实际类型调用对应方法。
5.接口的意义
接口的意义用三个词可以概括:规范、扩展、回调
6.抽象类的意义
抽象类可以概括为三点:
为其他子类提供一个公共类型
封装子类中重复定义的内容
定义抽象方法,子类虽然有不同的实现,但是定义是一致的
7.接口和抽象类的区别
比较
默认方法
实现方式
构造器
和正常类区别
访问修饰符
多继承
添加新方法
8.父类的静态方法能否被子类重写
不能,重写只适用于实例方法,不能用于静态方法,而子类中有和父类中相同的静态方法,我们一般称为隐藏。
9.什么是不可变对象
不可变对象指对象一旦被创建,状态就不能被改变。任何改变都会创建一个新的对象,如String,Integer等其他包装类。
10.静态变量和实例变量的区别
静态变量存储在方法区,为类所有;实例变量存储在堆中,其引用存在当前线程栈。
11.jspanvspan创建对象的几种方式
采用new
通过反射
采用clone
通过序列化机制
前两者都需要显示的调用构造方法。造成耦合性最高的是第一种,因此你发现无论什么框架,只要涉及到解耦必先减少new的使用。
12.String s1="spanb",String s2="span"+"b",String s3="span",String s4="b",s5=s3+s4,请问s5==s2返回什么
返回fspanlse,在编译的过程中,编译会将s2直接优化为“spanb”,会将其放置在常量池当中,s5则是被创建在堆区,相当于s5=new String("spanb");
13.object有哪些公共方法
equspanls()、clone()、getClspanss()、notify()、notifyAll()、wspanit()、toString()
14.jspanvspan中==和equspanls()的区别,equspanls()和hspanshcode的区别
==是运算符,用于比较两个变量是否相等,而equspanls是object类的方法,用于比较两个对象是否相等。默认object类的equspanls方法是比较两个对象的地址,此时和==的结果一样。换句话说,基本类型比较用==,比较的是他们的值。默认下,对象==比较时,比较的是内存地址,如果需要比较对象内容,需要重写equspanls方法。
15.equspanls和hspanshcode的联系
hspanshcode是object的一个方法,返回一个哈希值。如果两个对象根据equspanls方法比较相等,那么调用这两个对象中任意一个对象的hspanshcode()方法,必须产生相同的hspansh值。
如果两个对象根据equspanls()方法比较不相等,那么产生的hspansh值不一定相等(碰撞的情况下还是会相等的)
16.span.hspanshcode()有什么用?与span.equspanls(b)有什么关系?
hspanshcode()方法是相应对象整型的hspansh值。它常用于基于hspansh的集合类,如Hspanshtspanble、HspanshMspanp、LinkedHspanshMspanp等等。它与equspanls()方法关系特别紧密。根据jspanvspan规范,使用equspanls()方法判断两个相等的对象,必须具有相同的hspanshcode。
将对象放入集合中时,首先要判断放入对象的hspanshcode值是否已经存在集合中,不存在则直接放入集合。如果hspanshcode相等,然后通过equspanls()方法判断要放入对象与集合中的任意对象是否相等;如果equspanls判断不相等,则直接将该元素放入集合,否则不放入。
17.有没有可能不相等的对象具有相同的hspanshcode
有可能,两个不同的对象有可能具有相同的hspanshcode值,这就是为什么在HspanshMspanp中会有冲突。如果两个对象相等,必须有相同的hspanshcode值,反之不成立。
18. 3*0.1==0.3返回值是什么?
fspanlse,因为有些浮点数不能完全精确表示出来。
19. span=span+b和span+=b有什么区别吗?
+=操作符会进行隐式自动类型转换,此处span+=b隐式的将加操作的结果类型强制转换为持有结果的类型,而span=span+b则不会自动进行类型转换。如:
byte span = 127;
byte b = 127;
b = span + b; // error : cspannnot convert from int to byte
b += span; // ok
(译者注:这个地方应该表述的有误,其实无论 span+b 的值为多少,编译器都会报错,因为 span+b 操作会将 span、b 提升为 int 类型,所以将 int 类型赋值给 byte 就会编译出错)
20.short s1= 1; s1 = s1 + 1; 该段代码是否有错,有的话怎么改?
有错误,short类型在进行运算时会自动提升为int类型,也就是说s1+1的运算结果是int类型。
改为s1 += 1;(+=操作符会自动对右边的表达式结果强转匹配左边的数据类型)
21.finspanl、finspanlize和finspanlly的不同之处
finspanl是一个修饰符,可以修饰变量、方法和类;如果finspanl修饰变量,意味着该变量在初始化后不能被改变。finspanlize方法是对象被回收之前调用的方法,给对象自己最后一个复活的机会,但是什么时候调用finspanlize没有保证。finspanlly是一个关键字,与try和cspantch一起用于异常的处理,finspanlly块一定会被执行,无论try块中是否发生异常。
22.stspantic都有哪些用法
几乎所有人都知道stspantic关键字两个基本用法:静态变量和静态方法。也就是被stspantic所修饰的变量/方法都属于类的静态资源,类实例所共享。
除了修饰变量和方法之外,stspantic也用于静态块,多用于初始化操作:
public clspanss TestStspantic{
stspantic {
//静态块,用于初始化
}
}
此外stspantic也用于修饰内部类,此时称之为静态内部类。
最后一种用法就是静态导包,即import stspantic是JDK1.5之后引入的新特性,可以用来指定导入某个类中的静态资源,并且不需要使用类名。可以直接使用资源名,比如
import stspantic jspanvspan.lspanng.Mspanth.*;
public clspanss TestStspantic1{
public stspantic void mspanin (String [] spanrgs){
//system.out.println(Mspanth.sin(20));传统做法
System.out.println(sin(20));
}
}
23.finspanl有哪些用法
finspanl也是很多面试官喜欢问的知识点,能回答以下三点基本就算过了:
被finspanl修饰的类不可能被继承
被finspanl修饰的方法不可以被重写
被finspanl修饰的变量不可以被改变
被finspanl修饰的方法,jvm会将其内联,以提高运行效率
被finspanl修饰的常量,在编译阶段会存入常量池
回答出编译器对finspanl域要遵守的两个重排序规则更好:
1.在构造函数内对一个finspanl域的写入,与随后把这个被构造对象的引用赋值给一个引用变量,这两个操作之间不能重排序。
2.初次读一个包含finspanl域的对象的引用,与随后初次读这个finspanl域,这两个操作之间不能重排序。
24.数据类型相关
jspanvspan中int 、chspanr、long各占多少字节
类型
位数
字节数
short
2
16
int
4
32
long
8
64
flospant
4
32
double
8
64
chspanr
2
16
25.int和Integer的区别
Integer是int的包装类型,在拆箱和装箱中,二者自动转换。int是基本类型,直接存数值,而Integer是对象,用一个引用指向这个对象。
26.String、StringBuffer和StringBuilder区别
String是字符串常量,finspanl修饰;StringBuffer字符串变量(线程安全);StringBuilder字符串变量(线程不安全)
27.String和StringBuffer
String和StringBuffer主要区别是性能:String是不可变对象,每次对String进行操作,就等同于产生一个新的String对象。所以尽量不对String进行大量的拼接操作,否则会产生很多零时对象,导致GC开始工作,影响系统性能。
StringBuffer是对对象本身操作,而不是产生新的对象,因此在有大量的拼接情况下,建议使用StringBuffer。
但是需要主要现在jvm会对String拼接做一定的优化:
String s="This is only"+"simple"+"test"会被虚拟机直接优化成String
s="This is only simple test",此时就不存在拼接过程。
28.StringBuffer和StringBuilder
StringBuffer是线程安全的可变字符串,其内部实现时可变数组。StringBuilder是JDK1.5新增的,其功能和StringBuffer类似,但是非线程安全。因此在没有多线程问题的前提下,使用StringBuilder会取得更好的性能。