1.面向对象和面向过程的区别
面向过程:
性能高,调用类时需要实例化,开销大,消耗资源。
面向对象:
有封装、继承、多态的特性,易维护、易服用、易扩展,但是性能低。
2.传引用和传值
传值:
传递的是一个对象的拷贝,即使函数修改这个对象,也不会影响原对象值。
传引用:
对象本身没有被传递,传递的是引用地址,函数对这个引用修改,会影响原值。
3.基本类型和引用类型
byte、short、int、long、float、double、char、boolean;
基本数据类型:数据直接存储在栈上。
引用数据类型:数据存储在堆上,栈上只存储引用地址。
注意:String是引用类型。
4.128陷阱
public static void main(String[] args) {
Integer num1 = 100;
Integer num2 = 100;
System.out.println(num1 == num2);
Integer num3 = 128;
Integer num4 = 128;
System.out.println(num3 == num4);
}
1.如果在-128-127之间的数值都存储在一个catch数组当中,该数组相当于一个缓存;
2.在-128~127之间进行自动装箱(将数据存储到引用类型当中)直接返回该值在内存当中的地址;
3.所以在-128-127之间的数值用==进行比较是相等的;
4.而不在-128~127的数,需要新开辟一个内存空间,所以不相等。
5.自动装箱与拆箱
装箱(Autoboxing):
例:基本类型(int)—>引用类型(Integer)
int i = 10;
Integer in = new Integer(i);
拆箱(Unboxing):
例:引用类型(Integer)—>基本类型(Int)
自动装箱:
直接使用引用数据类型变量,接收基本数据类型元素。
Integer in3 = 100;
自动拆箱:
直接使用基本数据类型变量,接收引用数据类型变量;
直接使用引用数据类型变量,进行数据运算。
Integer in3 = 1000; int i3 = in3;
优点:
编译器会在编译期间根据语法决定是否进行自装箱和拆箱的动作,节省了常用数值的内存开销和创建对象的开销,提高了效率。
扩展:
在 JDK 中针对各种基本类型分别定义相应的引用类型 ————–称为封装类
Byte、Short、Integer、Long、Character、Float、Double、Boolean
6.String、StringBuilder和StringBuffer比较
String:
1.值被创建后不能修改,任何对String的修改都会引发新的String对象的生成。
2.两种定义方式:new对象;可接受一个堆内存中的对象。
3.字符串拼接效率低。
StringBuffer:
1.跟String类似,值被创建后可以被修改,使用synchronized来保证线程安全。
2.JDK1.0后有的。
StringBuilder:
1.非线程安全,性能高,推荐使用。
2.jdk1.5后有的。
3.字符串拼接效率高。
7.String s = new String(xyz) 创建了几个字符串对象?
1、String s = new String("xyz") 创建了几个字符串对象?
如果字符串常量池已经有“xyz”,则是一个,否则两个:
一个是字符串字面量“xyz”所对应的、驻留(intern)在一个全局共享的字符串常量池中的实
例,此时该实例也是在堆中,字符串常量池只放引用。
一个是通过new String()创建并初始化的,内容与“xyz”相同的实例,也是在堆中。
2、String s = "xyz" 和 String s = new String("xyz") 区别?
两个语句都会先去字符串常量池中检查是否已经存在"xyz",如果有则直接使用,如果没有则会在常量池中直接创建"xyz"对象。
String s = new String("xyz")还会通过new string()创建一个内容与"xyz"相同的对象实例。
可以理解为String s = new String("xyz")包含String s = "xyz"。
8.字符型常量和字符串常量的区别
形式上:
字符型常量是单引号引起来;
字符串常量是双引号引起来。
含义上:
字符常量相当于一个整型值(ASCII码值),可以进行表达式运算;
字符串常量代表一个地址值,在内存中存放引用地址。
内存上:
字符常量占一个字节;
字符串常量占若干字节(至少一个字符结束标志)。
9.静态变量和非静态变量的区别
相同点:
都属于成员变量。
1.存储空间不同:
静态变量:在方法区存储。
非静态变量:在堆内存存储。
2.生命周期不同:
静态变量:随着类的加载存在,随着类的回收消失。
非静态变量:随着对象的创建存在,随着对象回收消失。
3.调用方式不同:
静态变量:可以使用对象调用,也可以使用类名调用。
非静态变量:只能使用对象调用。
10.局部变量和成员变量之间的区别
1、定义位置不同。
局部变量:在方法中定义。
成员变量:在类中方法外定义。
2、存储空间不同:
局部变量:栈内存存储。
成员变量:堆内存存储。
3、生命周期不同:
局部变量:随着方法的调用而存在,方法的结束而消失。
成员变量:随着对象的创建而存在,随着对象的空间回收而消失。
4、默认值不同:
局部变量:没有默认值,不赋值不能使用。
成员变量:有默认值。String:null; Char:' '; Double:0.0;
11.static方法可以被override吗?
static,静态,被static修饰的成员变量,被访问时不必实例化对象,只需类名.变量名。override的机制是Run time的动态绑定,static是Compile time的静态绑定,static方法不与任何类的具体实例有关。
12.什么是静态绑定和动态绑定
绑定:一个方法的调用与方法所在的类相关联。
动态绑定:
1.方法在程序运行时根据对象类型绑定。
2.使用的是对象信息。
静态绑定:
1.方法在程序编译期进行绑定。
2.使用的是类信息。
注意:
1.private,final和,tatic方法和变量使用静态绑定;
虚函数(virtual)根据运行时的具体对象进行绑定。
2.overload使用的是静态绑定;
override使用的是动态绑定。
扩展:
虚函数:
在Java中,所有的方法默认都是虚函数,只有以final修饰的方法才是非虚函
数,虚函数是面向对象编程实现多态的基本手段。
13.为什么使用static
不使用静态:
如果一个类型的多个对象中某一个属性值都相同,需要分别在对象中为这个相同的值分配内存。如果需要将这个相同的属性值统一修改,每个对象都要修改一次,浪费内存空间,不易维护。
使用静态:
多个对象某一个属性值如果都相同,可以将该属性定义为静态修饰,不需要为每一个对象都分配一段空间来存储该属性,后续想要修改属性值,只修改一次即可,节约内存。
14.Constructor是否可被override
首先,Constructor不能被继承,所以更不能被override,但是可以被overload。
原因1:
子类继承了父类的构造方法,构造方法名字无法和类名一致。
原因2:
父类的构造方法是给父类的属性初始化,如果子类继承了父类构造方法,而且子类中有
一个自己的特殊属性,从父类中继承的构造方法不能给自己的属性初始化,所以子类不
能继承父类构造方法。
15.override和overload的区别
override:
实现的是编译时的多态性;
发生在子类与父类之间,子类对父类的方法进行重写,参数不能变,返回值类型可以不同,但必须是父类返回值的派生类(外壳不变,核心重写)。
好处:子类可以根据需要,定义特定于自己的行为。
overload:
实现的是运行时的多态性;
一个类中有多个同名的方法,但是具有不同参数列表(参数类型或个数不同)
16.创建一个对象用什么运算符,对象实体与对象引用有何不同
用new运算符创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。一个对象的引用可以指向0个或1个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有n个引用指向它(可以用n条绳子系住一个气球)
17.匿名对象的使用场景和优点
使用场景:
1、当只需要调用某对象的方法一次。
2、当传递一个对象的时候,可以使用匿名对象来当实参传递。
3、当方法需要返回一个对象,可以返回一个匿名对象。
优点:
不用创建一个空间存储对象地址,节约内存。
18.方法的调用方式
直接调用:
getMax(1,2),当方法没有返回值时。
输出调用:
getMax(a,b),当方法有返回值,只想将返回值打印输出。
赋值调用:
int x= getMax(a.b),当方法有返回值,并反复使用。
19.方法中,变量的访问规则
在方法中,使用一个变量,首先在当前方法查找,如果有定义直接使用;
如果方法中没有定义就去对象中寻找,有就使用,没有就报错。
20.this关键字访问变量的规则
如果使用某一变量,该变量没有通过this修饰,根据就近原则访问;
如果使用某一变量,该变量使用this修饰,直接表示对象中存储的属性。
21.分别说明:在类上、在属性上、在方法上能使用哪些访问修饰符
在类上:
public,default,final
在方法上:
访问权限:public,protected,private,default
方法修饰符:static,final
返回类型:void
在属性上:
public,protected,private,default,static,final
22.接口和抽象类的区别
1、接口的方法默认是public,所有方法在接口中不能有实现,抽象类可以有非抽象的方法。
2、接口中的实例变量默认是final类型,抽象类中不一定。
3、一个类可以实现多个接口,但最多只能实现一个抽象类。
4、一个类要实现接口,要实现接口的所有方法,而抽象类不一定。
5、接口不能用new实例化,但可以声明,但是必须引用一个实现该接口的对象。从设计层面 来说,抽象是对类的抽象,是一种模板设计;接口是行为的抽象,是一种行为规范。
23.final关键字
final修饰类型:
使用final修饰的类型,不能有子类。
final修饰方法:
使用final修饰的方法,方法不能被子类重写,可以被继承。
final修饰变量:
使用final修饰的变量,变为常量,这个常量有名字定义(字面值常量/符号常量),不能
被修改。
24.switch()语句括号内值类型
括号内必须是byte、char、short、int、String、枚举类型之一。
25.列举跳转语句并说明
continue:
结束当前这一次循环,继续执行下次循环。
break:
结束所在当前层循环。
return:
结束所在的整个方法。
System.exit(0):
结束所在的JVM虚拟机。
24.权限修饰符
private:只能在本类中被直接访问。
默认:可以在本类中、本包的其他类被直接访问。
protected:可以在本类中、本包其他类、子类中被直接访问。
public:可以在本类中、本包其他类、子类中、其他包无关类中被直接访问。
25.GBK编码与UTF-8编码
GBK编码表中:
定义一个英文字符,使用一个字节存储;
定义一个字符,使用两个字节存储。
UTF-8编码表中:
定义一个英文字符,使用一个字节存储;
定义一个中文字符,使用三个字节存储。
26.&和&&的区别
&&:逻辑与
运算符左右两边的表达式都为true时,才返回true。
具有短路性:如果第一个表达式值为false,则直接返回false。
&:逻辑与、按位与
逻辑与:不具有短路性。
按位与:(常用)。
27.== 和 equals 比较
1、相同点:
两个都是用来比较数据是否相同的,如果相同为真,不同为假。
2、不同点:
(1)比较的内容不同:
==:既可以比较基本数据类型,也可以比较引用数据类型。
equals:只可以比较引用数据类型,不能比较基本数据类型。
(2)比较的规则不同:
==:如果比较的是基本数据类型,比较的是数据的值是否相同。
==:如果比较的是引用数据类型,比较的是对象的地址值是否相同。
equals:比较引用数据类型,如果重写了,比较属性值,如果没有重写比较地址值。
28.final、finally和finalize的区别
final:
1.被final修饰的类,不能再派生新的子类;
2.被final修饰的类,不能被实例化对象;
3.一个类不能既被abstract声明,又被final声明(被abstract修饰后,就成为抽象类,不能被实例化对象,只有通过子类继承完成这个抽象类的功能,但是被final修饰后,类不能被继承,是一个终态类。);
4.被final修饰的变量,必须给出初始值;
5.被final修饰的方法,不能被重写;
6.被final修饰的变量或方法,不能被修改。
finally:
1.在异常处理时,不管有没有异常被抛出、捕获,finally块中的代码都会执行;
2.必须和try联合使用。
finalize():
1.finalize()方法在垃圾收集器将对象从内存中清除前被调用,做内存清理工作。
2.在Object类中定义,所有类都继承了它。
29.StringBuilder的构造方法
1.StringBuilder():
创建一个初始值为空的字符串对象,数组的初始化大小为16。
2.StringBuilder(int c):
创建一个初始值为空的字符串对象,数组的初始化大小为c。
3.StringBuilder(String str):
创建一个初始值为str的字符串对象,数组初始化大小为str.length() + 16。
30.接口和方法中变量的默认修饰符
接口中:public static final
方法中:public abstract
31.String类为什么设计成final的
1.节省空间,String类型常量存储在JVM的字符串常量池中可被用户共享。
2.安全,被final修饰,不可被恶意更改。
3.效率高,可被不同线程共享,是线程安全的,在多线程操作中不需要进行同步操作。