Java 基础知识面试点

1、三大特性概述

封装,继承,多态

 

多态分为编译时多态(方法重载)和运行时多态(方法重写)。要实现多态需要做
两件事:一是子类继承父类并重写父类中的方法,二是用父类型引用子类型对象,这样同
样的引用调用同样的方法就会根据子类对象的不同而表现出不同的行为

 

2、重载(Overload)和重写(Override)的区别?【重点】


重载:编译时多态、同一个类中、同名的方法具有不同的参数列表、不能根据返回类
型进行区分【因为:函数调用时不能指定类型信息,编译器不知道你要调哪个函数】;
重写(又名覆盖):运行时多态、子类与父类之间、子类重写父类的方法具有相同的
返回类型、更好的访问权限。

 

3、Java 中是否可以重写(Override)一个 private 或者
static 方法?


Java 中 static 方法不能被覆盖,因为方法覆盖是基于运行时动态绑定的,而 static 方
法是编译时静态绑定的。static 方法跟类的任何实例都不相关,所以概念上不适用。
静态的方法可以被继承,但是不能重写。如果父类和子类中存在同样名称和参数的静
态方法,那么该子类的方法会把原来继承过来的父类的方法隐藏,而不是重写。通俗
的讲就是父类的方法和子类的方法是两个没有关系的方法,具体调用哪一个方法是看
是哪个对象的引用;这种父子类方法也不在存在多态的性质 【即 Father father =
new child(); father 这个引用调用的是父类里的静态方法。如果是多态,那么 father
应该调用的子类的方法】
Java 中也不可以覆盖 private 的方法,因为 private 修饰的变量和方法只能在当前类
中使用, 如果是其他的类继承当前类是不能访问到 private 变量或方法的,当然也不能覆
盖。

 

4、Java 中创建对象的几种方式?


1、使用 new 关键字;
2、使用 Class 类的 newInstance 方法,该方法调用无参的构造器创建对象(反射):
Class.forName.newInstance();
3、使用 clone() 方法;
4、反序列化,比如调用 ObjectInputStream 类的 readObject() 方法。

 

5、抽象类和接口有什么不同?【重点】


不同点:
1、抽象类中可以定义构造函数,接口不能定义构造函数;
2、抽象类中可以有抽象方法和具体方法,而接口中只能有抽象方法(public abstract);
3、抽象类中的成员权限可以是 public、默认、protected(抽象类中抽象方法就是为了重
写,所以不能被 private 修饰),而接口中的成员只可以是 public(方法默认:public
abstrat、成员变量默认:public static final);
在 Java8 中,允许在接口中包含带有具体实现的方法,使用 default 修饰,这类方法
就是默认方法。
4、抽象类中可以包含静态方法,而接口中不可以包含静态方法;
抽象类中可以包含静态方法,在 JDK1.8 之前接口中不能包含静态方法,JDK1.8 以后
可以包含。之前不能包含是因为,接口不可以实现方法,只可以定义方法,所以不能
使用静态方法(因为静态方法必须实现)。现在可以包含了,只能直接用接口调用静
态方法。1.8 仍然不可以包含静态代码块。
接口的成员变量默认是 public static final,static 是为了保证变量只有一份,因为一
个类可以实现多个接口,定义为 static 后,如果出现重名,那么存储在静态存储区的
时候就会报错,因为静态存储区已经有一份了,你改名吧(成员变量可以通过接口和
实现接口的类来调用)。final 是因为接口的东西是大家共用的,不能随便修改。
相同点:
1、都不能被实例化;
2、可以将抽象类和接口作为引用类型;
3、一个类如何继承了某个抽象类或者实现了某个接口,就必须对其中所有的抽象方法全部
进行实现,否则该类仍然需要被声明为抽象类。

 

5、switch 语句能否作用在 byte 上,能否作用在 long 上,能
否作用在 String 上?


在 switch(expr 1) 中,expr1 只能是一个整数表达式或者枚举常量。而整数表达式可
以是 int 基本数据类型或者 Integer 包装类型。由于,byte、short、char 都可以隐式转
换为 int,所以,这些类型以及这些类型的包装类型也都是可以的。而 long 和 String 类
型都不符合 switch 的语法规定,并且不能被隐式的转换为 int 类型,所以,它们不能作用
于 switch 语句中。不过,需要注意的是在 JDK1.7 版本之后 switch 就可以作用在
String 上了。

 

2、String、StringBuilder、StringBuffer的区别【重点】?


1、String:用于字符串操作,属于不可变类;【补充:String 不是基本数据类型,是引用
类型,底层用 char 数组实现的】
2、StringBuffer:也用于字符串操作,不同之处是 StringBuffer 属于可变类,对方法加了
同步锁,线程安全;
说明:StringBuffer 中并不是所有方法都使用了 Synchronized 修饰来实现同步:
上诉方法通过调用超类 AbstractStringBuilder 中的方法,将 s 转换为 String。
3、StringBuilder:与 StringBuffer 类似,都是字符串缓冲区,但线程不安全。
执行效率:StringBuilder > StringBuffer > String
String 字符串修改实现的原理:当用 String 类型来对字符串进行修改时,其实现方
法是首先创建一个 StringBuffer,其次调用 StringBuffer 的 append() 方法,最后调用
StringBuffer 的 toString() 方法把结果返回。
3

 

1.1、final、finally、finalize 的区别?


final: 用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖、被其修饰的类不
可继承;
finally: 异常处理语句结构的一部分,表示总是执行;
finallize: Object类的一个方法,在垃圾回收时会调用被回收对象的finalize。

 

3、static


3.1、静态变量
静态变量: 又称为类变量,也就是说这个变量属于类的,类所有的实例都共享静态变量,
可以直接通过类名来访问它。静态变量在内存中只存在一份。
实例变量: 每创建一个实例就会产生一个实例变量,它与该实例同生共死。
3.2、静态方法
静态方法在类加载的时候就存在了,它不依赖于任何实例。所以静态方法必须有实
现,也就是说它不能是抽象方法。只能访问所属类的静态字段和静态方法,方法中不能有
this 和 super 关键字。
3.3、静态语句块
静态语句块在类初始化时运行一次。
3.4、静态内部类
非静态内部类依赖于外部类的实例,而静态内部类不需要。静态内部类不能访问外部
类的非静态的变量和方法。

 

1、== 和 equals 的区别?


==: 如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数
据类型,则比较的是对象的地址值是否相等;
equals方法: 用来比较两个对象的内容是否相等;注意:equals 方法不能用于比较基本
数据类型的变量。如果没有对 equals 方法进行重写,则比较的是引用类型的变量所指向的
对象的地址。(很多类重新了 equals 方法,比如 String、Integer 等把它变成了值比较,
所以一般情况下 equals 比较的是值是否相等)

 

hashCode()与equals()的相关规定:
1、如果两个对象相等,则 hashCode 一定也是相同的;
2、两个对象相等,对两个对象分别调用 equals 方法都返回 true;
3、两个对象有相同的 hashCode 值,它们也不一定是相等的;

 

4、& 和 && 的区别?
Java中 && 和 & 都是表示与的逻辑运算符,都表示逻辑运输符 and,当两边的表达
式都为 true 的时候,整个运算结果才为 true,否则为 false。
&&: 有短路功能,当第一个表达式的值为 false 的时候,则不再计算第二个表达式;
&: 不管第一个表达式结果是否为 true,第二个都会执行。除此之外,& 还可以用作位运
算符:当 & 两边的表达式不是 Boolean 类型的时候,& 表示按位操作。

 

5、参数传递
https://blog.****.net/pcwl1206/article/details/86550268
Java 的参数是以值传递的形式传入方法中,而不是引用传递。
当传递方法参数类型为基本数据类型(数字以及布尔值)时,一个方法是不可能修改
一个基本数据类型的参数。
当传递方法参数类型为引用数据类型时,一个方法将修改一个引用数据类型的参数所
指向对象的值。
即使 Java 函数在传递引用数据类型时,也只是拷贝了引用的值罢了,之所以能修改引
用数据是因为它们同时指向了一个对象,但这仍然是按值调用而不是引用调用。

 

 

Java 基础知识面试点

 

1、error 和 exception 的区别?

 


Error 类和 Exception 类的父类都是 Throwable 类。主要区别如下:
Error类: 一般是指与虚拟机相关的问题,如:系统崩溃,虚拟机错误,内存空间不足,
方法调用栈溢出等。这类错误将会导致应用程序中断,仅靠程序本身无法恢复和预防;
Exception 类:分为运行时异常和受检查的异常。
运行时异常:【如空指针异常、指定的类找不到、数组越界、方法传递参数错误、数
据类型转换错误】可以编译通过,但是一运行就停止了,程序不会自己处理;
受检查异常:要么用 try … catch… 捕获,要么用 throws 声明抛出,交给父类处理。

 

1、如何实现对象的克隆?


两种方式:
1、实现 Cloneable 接口并重写 Object 类中的 clone() 方法;
2、实现 Serializable 接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深克
隆。
注意:深克隆和浅克隆的区别:
1、浅克隆:拷贝对象和原始对象的引用类型引用同一个对象。浅克隆只是复制了对象的引
用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变
化,这就是浅克隆(例:assign())。
2、深克隆:拷贝对象和原始对象的引用类型引用不同对象。深拷贝是将对象及值复制过
来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝(例:JSON.parse() 和
JSON.stringify(),但是此方法无法复制函数类型)。
深克隆的实现就是在引用类型所在的类实现 Cloneable 接口,并使用 public 访问修
饰符重写 clone 方法;
Java 中定义的 clone 没有深浅之分,都是统一的调用 Object 的 clone 方法。为什
么会有深克隆的概念?是由于我们在实现的过程中刻意的嵌套了 clone 方法的调用。
也就是说深克隆就是在需要克隆的对象类型的类中重新实现克隆方法 clone()。