1、final 作用?
主要用于修饰类、属性和方法。
- 修饰类,不可以被继承 {编译器:Cannot inherit from final}
- 修饰方法,不可以被重写 {编译器:overridden method is final}
- 修饰变量,不可以被改变【修饰的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的】{例如:final Map map = new HashMap<>() }
2、final、finally、finalize区别?
- final 可以修饰类、变量、方法,【关键字1】
- finally 一般作用在try-catch代码块中,处理异常时,不管是否出现异常,该代码块都会执行,一般存放一些关闭资源的代码
- finalize 是一个属于Object类的一个方法,而Object类是所有类的父类,一般由垃圾回收器来调用
3、什么是多态机制?Java语言是如何实现多态的?
父类的引用指向子类的实现
实现多态的条件:继承、重写、向上转型
4、面向对象的基本原则?
- 单一职责原则
- 开放封闭原则
- 里氏代换原则
- 依赖倒置原则
- 接口分离原则
5、抽象类和接口对比?
关键字描述:抽象类是捕捉子类通用特性的。接口是抽象方法的集合。从设计层面说,抽象类是对类的抽象,是一种模板设计。接口是行为的抽象,是一种行为的规范。
相同点:
- 接口和抽象类都不能实例化
- 都位于继承的顶端,用于被实现或继承
- 都包含抽象方法,子类必须覆写这些抽象方法
不同点:
- 声明不同,抽象类使用abstract,接口使用interface
- 实现不同,抽象类-子类使用extends继承,如果子类不是抽象类的话,需要提供抽象类中声明的抽象方法的实现。接口-子类使用implement实现,需要提供接口中声明的所有方法。
- 构造器,抽象类可以由构造器,接口不能
- 访问修饰符,抽象类可以任意,接口默认为public 不能为private,protected
- 继承,抽象类可以单继承,接口可以多实现
- 字段,抽象类可以任意,接口默认是static和public
在接口和抽象类的选择上,遵循的原则:
- 行为模型应该总是通过接口而不是抽象类定义,所以通常优先选择接口,尽量少用抽象类。
- 选择抽象类的情况:需要定义子类的行为,又要为子类提供通用的方法。
6、内部类的分类?
- 静态内部类:【描述】:定义在类内部的静态类【特点】:可以访问外部类所有的静态变量,不可以访问外部类的非静态变量,创建方式-new 外部类.静态内部类()
- 成员内部类:【描述】:定义在类内部成员位置上的非静态类【特点】:可以访问外部类的所有变量和方法,创建方式-外部类实例.new 内部类()
- 局部内部类:【描述】:定义在方法中的内部类【特点】:定义在实例方法中的局部类可以访问外部类的所有方法和变量,定义在静态方法中的局部类只能访问外部类的静态变量和方法,创建方式-在对应方法内 new 内部类()
- 匿名内部类:【描述】:~ 常用【特点】:1、没有名字,2、必须继承一个抽象类或实现一个接口,3、不能定义任何静态成员和静态方法,4、当所在的方法的形参需要被匿名内部类使用时,必须声明为final,5、不能是抽象的,必须要实现继承的类或实现接口的所有抽象方法,创建方式-new 抽象类或接口{匿名内部类实现的部分}
7、局部内部类和匿名内部类在访问局部变量时,为什么变量要加上final?
因为生命周期不一致,局部变量存储于栈中,当方法执行结束后,非final的局部变量被销毁。而局部内部类对局部变量的引用依然存在,那么如果局部内部类要调用该局部变量时,就会出错。
public class Outer{
private int age = 12;
Class Inner{
private int age = 13;
public void print(){
int age = 14;
System.out.println("局部变量:"+age);
System.out.println("内部类变量:"+this.age);
System.out.println("外部类变量:"+age);
}
}
public static void main(String args[]){
Outer.Inner in = new Outer().new Inner();
in.print();
}
}
8、构造器是否可以被重写?
构造器不能被继承,因此不能被重写,可以被重载
9、重载和重写区别?
方法的重载和重写都是实现多态的方式。前者为编译时多态性,后者为运行时多态性
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同,个数不同,顺序不同),与方法返回值和访问修饰符无关,即重载不能根据返回类型进行区分
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于父类,访问修饰符要大于等于父类(里氏代换原则)。如果父类方法的访问修饰符为private则子类就不能是重写
10、==和equals区别?
- ==:是判断两个对象的地址是否相等,即判断两个对象是否为同一个对象。{基本数据类型比较的是值,引用数据类型比较的是内存地址}
- equals:判断两个对象是否相等
- 类没有覆盖equals方法,比较类的两个对象时,等价于==比较对象的内存地址
- 类覆盖equals方法,一般判断两个对象的内容是否相等
11、hashcode 与 equals?
hashcode作用是获取哈希码(散列码)是确定对象在哈希表中的索引位置。
- 如果两个对象相等,则hashcode一定也相同
- 两个对象相等,则两个对象分别调用equals方法都返回true
- 两个对象有相同的hashcode值,这两个对象也不一定相等
12、对象相等与指向他们的引用相等不同?
对象相等比的是内存中存放的内容是否相等;引用相等比较的是他们指向的内存地址是否相等
13、当一个对象被当作参数传递到一个方法后,此方法可以改变这个对象的属性,并可返回变化后的结果,是值传递?引用传递?
是值传递。Java中方法调用只支持参数的值传递
14、使用HashMap时,用String做key有什么好处?
其内部实现是通过key的hashcode来确定value的存储位置,因为String不可变,所以创建字符串时,hashcode被缓存,不需要再次计算,所以相比其他对象要更快