1.面向对象的三个特征
封装,继承,多态,这个应该是人人皆知,有时候也会加上抽象。
2.多态的好处
允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。主要有以下优点:
- 可替换性:多态对已存在代码具有可替换性
- 可扩充性:增加新的子类不影响已经存在的类结构
- 接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现的。
- 灵活性
- 简化性
3.代码中如何实现多态
实现多态主要有以下三种方式:
- 接口实现
- 继承父类重写方法
- 同一类中进行方法重载
4.接口的意义
接口的意义用三个词就可以概括:规范,扩展,回调。
1.接口的作用 2.接口的深入理解
5.抽象类的意义
抽象类的意义可以用三句话来概括:
为其他子类提供一个公共的类型
封装子类中重复定义的内容
定义抽象方法,子类虽然有不同的实现,但是定义时一致的
6.接口和抽象类的区别
7.父类的静态方法能否被子类重写
不能。重写只适用于实例方法,不能用于静态方法,而子类当中含有和父类相同签名的静态方法,我们一般称之为隐藏。
public class Parent {//父类对象 |
8.静态属性和静态方法是否可以被继承
可以被继承,如果子类中有相同的静态方法和静态变量,那么父类的方法以及变量就会被覆盖。要想调用就就必须使用父类来调用。
class Fruit{ |
从上述代码可以看出,子类中覆盖了父类的静态方法的话,调用的是子类的方法,这个时候要是还想调用父类的静态方法,应该是用父类直接调用。如果子类没有覆盖,则调用的是父类的方法。静态变量与此相似。
9.什么是不可变对象
- 不可变对象(Immutable Objects)即对象一旦被创建它的状态(对象的数据,也即对象属性值)就不能改变,任何对它的改变都应该产生一个新的对象。
- 可变对象(Mutable Objects):相对于不可变类,可变类创建实例后可以改变其成员变量值,开发中创建的大部分类都属于可变类。
- 不可变对象的类即为不可变类(ImmutableClass)。JAVA平台类库中包含许多不可变类,如String、Integer基本类型的包装类、BigInteger和BigDecimal等。
不可变对象优点:
- 构造、测试和使用都很简单
- 不可变对象是线程安全的,在线程之间可以相互共享,不需要利用特殊机制来保证同步问题,因为对象的值无法改变。可以降低并发错误的可能性,因为不需要用一些锁机制等保证内存一致性问题也减少了同步开销。
- 不可变对象可以被重复使用,可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。
缺点:
- 不可变对象最大的缺点就是创建对象的开销,因为每一步操作都会产生一个新的对象,制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,会创造很多的垃圾,给垃圾收集带来很大的麻烦
10.静态变量和实例变量的区别?
静态变量存储在方法区,属于类所有。实例变量存储在堆当中,其引用存在当前线程栈。
语法区别:静态变量需要static关键字修饰,实例变量不需要。
程序运行时的区别:静态变量从属于类,实例变量从属于对象。
实例变量必须创建了实例对象,其中的实例变量才会被分配空间,才能使用这个实例变量;
静态变量即类别量,只要程序加载了类的字节码,静态变量就会被分配空间,即可使用。
综上,实例变量必须创建对象后通过这个对象来使用,静态变量可以直接使用类名来引用。
public class BainLiang { |
非静态方法可以调用静态方法与变量,静态方法不能调用实例对象
11.能否创建一个包含可变对象的不可变对象?
当然可以创建一个包含可变对象的不可变对象的,你只需要谨慎一点,不要共享可变对象的引用就可以了,如果需要变化时,就返回原对象的一个拷贝。最常见的例子就是对象中包含一个日期对象的引用。
12.java 创建对象的几种方式
1.采用new
2.使用Class类的newInstance方法
Student student2 = (Student)Class.forName("根路径.Student").newInstance(); |
3.Constructor类的newInstance方法(反射)
本方法和Class类的newInstance方法很像,java.lang.relect.Constructor类里也有一个newInstance方法可以创建对象。我们可以通过这个newInstance方法调用有参数的和私有的构造函数。
Constructor<Student> constructor = Student.class.getInstance(); |
这两种newInstance的方法就是大家所说的反射,事实上Class的newInstance方法内部调用Constructor的newInstance方法。这也是众多框架Spring、Hibernate、Struts等使用后者的原因。
4.采用clone
5.通过序列化机制
前2者都需要显式地调用构造方法。造成耦合性最高的恰好是第一种,因此你发现无论什么框架,只要涉及到解耦必先减少new的使用。
13.switch中能否使用string做参数
在idk 1.7之前,switch只能支持byte, short, char, int或者其对应的封装类以及Enum类型。从idk 1.7之后switch开始支持String。
14.switch能否作用在byte, long上?
可以用在byte上,但是不能用在long上。
15.String s1=”ab”, String s2=”a”+”b”, String s3=”a”, String s4=”b”, s5=s3+s4请问s5==s2返回什么?
返回false。在编译过程中,编译器会将s2直接优化为”ab”,会将其放置在常量池当中,s5则是被创建在堆区,相当于s5=new String(“ab”);
16.你对String对象的intern()熟悉么?
intern()方法会首先从常量池中查找是否存在该常量值,如果常量池中不存在则现在常量池中创建,如果已经存在则直接返回。
比如
String s1=”aa”;
String s2=s1.intern();
System.out.print(s1==s2);//返回true
17.Object中有哪些公共方法?
equals()
clone()
getClass()
notify(),notifyAll(),wait()
toString
18.java当中的四种引用
强引用,软引用,弱引用,虚引用。不同的引用类型主要体现在GC上:
强引用:如果一个对象具有强引用,它就不会被垃圾回收器回收。即使当前内存空间不足,JVM也不会回收它,而是抛出 OutOfMemoryError 错误,使程序异常终止。如果想中断强引用和某个对象之间的关联,可以显式地将引用赋值为null,这样一来的话,JVM在合适的时间就会回收该对象。
软引用:在使用软引用时,如果内存的空间足够,软引用就能继续被使用,而不会被垃圾回收器回收,只有在内存不足时,软引用才会被垃圾回收器回收。
弱引用:具有弱引用的对象拥有的生命周期更短暂。因为当 JVM 进行垃圾回收,一旦发现弱引用对象,无论当前内存空间是否充足,都会将弱引用回收。不过由于垃圾回收器是一个优先级较低的线程,所以并不一定能迅速发现弱引用对象。
虚引用:顾名思义,就是形同虚设,如果一个对象仅持有虚引用,那么它相当于没有引用,在任何时候都可能被垃圾回收器回收。
19.WeakReference与SoftReference的区别?
这点在四种引用类型中已经做了解释,这里简单说明一下即可:
虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候。
20.为什么要有不同的引用类型
不像C语言,我们可以控制内存的申请和释放,在Java中有时候我们需要适当的控制对象被回收的时机,因此就诞生了不同的引用类型,可以说不同的引用类型实则是对GC回收时机不可控的妥协。有以下几个使用场景可以充分的说明:
1.利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题.
2.通过软引用实现Java对象的高速缓存:比如我们创建了一Person的类,如果每次需要查询一个人的信息,哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这将引起大量Person对象的消耗,并且由于这些对象的生命周期相对较短,会引起多次GC影响性能。此时,通过软引用和 HashMap 的结合可以构建高速缓存,提供性能。
21.重载和重写的区别? 子类可以重载父类的方法吗?
答:重载:指的是同名的方法拥有不同的参数列表,而系统调用函数是能够根据参数列表选择正确的方法。
重写:指的是是对父类方法的一种覆盖。
子类不可以重载父类的方法,只能重写。