Java基础知识总结

1、Java语言为什么是跨平台的(平台无关性)

答:JVM实现了Java语言最重要的特征:即平台无关性。原理:编译后的 Java 程序指令并不直接在硬件系统的 CPU 上执行,而是由 JVM 执行。JVM屏蔽了与具体平台相关的信息,使Java语言编译程序只需要生成在JVM上运行的目标字节码(.class),就可以在多种平台上不加修改地运行。Java 虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。因此实现java平台无关性。

- 2、final,finalize,finally的异同点

答:final :final修饰的变量(属性)不能被修改,修饰的方法不能被重写,修饰的类不能被继承。
finally :finally是在异常处理时提供finally块来执行任何清除操作。不管有没有异常被抛出、捕获,finally块都会被执行。try块中的内容是在无异常时执行到结束。catch块中的内容,是在try块内容发生catch所声明的异常时,跳转到catch块中执行。finally块则是无论异常是否发生,都会执行finally块的内容,所以在代码逻辑中有需要无论发生什么都必须执行的代码,就可以放在finally块中。try{}catch{}finally{}
finalize :是方法名。java技术允许使用finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在object类中定义的,因此所有的类都继承了它。子类覆盖finalize()方法以整理系统资源或者被执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

- 3、JVM的类加载流程(7个步骤)

答:类从被虚拟机加载到内存开始,直到卸载出内存为止,整个生命周期包括:加载——验证——准备——解析——初始化——使用——卸载 。 其中验证、准备、解析3个部分统称为连接。

- 4、JVM的双亲加载机制?父子类之间构造方法的调用机制?递归调用父类的构造方法?

答:类加载器的双亲委派加载机制: 当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载都是如此,因此所有的加载请求都应该传送到启动类加载器中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径里找不到这个所需要加载的类),子类加载器才会尝试自己去加载。
在这里插入图片描述
父子类之间构造方法的调用机制:有两个类,他们是父子类,这两个类中,都有自己的构造方法,当创建父类对象的时候,它会执行父类构造方法,当创建子类对象的时候,它会选执行父类的构造方法,然后再执行子类的构造方法。
递归调用父类的构造方法:递归调用就是在new一个子类对象时,先调用它父类的构造方法,父类还得在调用他的那个父类,就一直调用下去,结束条件就是遇到Object类了才不会继续调用了。
子类递归调用父类的构造方法与jvm双亲加载机制(当某个特定的类收到类加载请求时会依次向他的父类发送请求,如果父类可以完成则返回,若不能完成则子类自身完成。)有关。

父类如果不显示地写无参构造方法(函数)子类就无法调用这个无参构造方法。

- 5、Java的垃圾回收机制?

答:自动垃圾回收是一种在堆内存中找出哪些对象在被使用,还有哪些对象没被使用,并且将后者删掉的机制。所谓使用中的对象(已引用对象),指的是程序中有指针指向的对象;而未使用中的对象(未引用对象),则没有被任何指针给指向,因此占用的内存也可以被回收掉。
在用 C 之类的编程语言时,程序员需要自己手动分配和释放内存。而 Java 不一样,它有垃圾回收器,释放内存由回收器负责。
第一步标记,垃圾回收器此时会找出哪些内存在使用中,还有哪些不是;第二步清除,这一步会删除标记的未引用对象,内存分配器会保留只想可用内存的引用,以供分配新对象;第三步压缩,为了提升性能,删除了未引用对象后,还可以将剩下的已引用对象放在一起(压缩),这样就能更简单快捷的分配新对象了。

- 6、强引用、弱引用、软引用、虚引用

答: 强引用 :被刚new出来的对象所加上的运用,永远不会被回收
软引用 :被声明为软引用的类,是可被回收的对象,如果jvm内存紧张则软引用被回收,否则不会被回收。为什么不被直接回收?缓存的对象可有可无,留在内存中可能被需要,所以就不需要重新被分配内存了。软引用可以加速JVM对垃圾内存的回收速度。
弱引用 (一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。)、
虚引用(虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。),
这 4 种引用的强度依次减弱。
https://blog.csdn.net/Hacker_ZhiDian/article/details/83043270

- 7、基本类型各占几个字节?boolean类型占几个字节?

在这里插入图片描述
答:boolean类型没有给出精确的定义,《Java虚拟机规范》给出了4个字节,和boolean数组1个字节的定义,具体还要看虚拟机实现是否按照规范来,所以1个字节、4个字节都是有可能的。这其实是运算效率和存储空间之间的博弈,两者都非常的重要。
Boolean类型在不同平台所占的字节不同。

8、基本类型中的自动(默认)转换和强制转换?注意:byte、short、char混合运算时,表达式最终类型是int类型

在这里插入图片描述
当大容量的变量向小的变量的类型去转换时需要强制转换 ,数值类型的转换前提要保证精度不会损失的情况下才可以强制转换;小数转换成整数,就是把小数点后面的数给去掉。boolean类型的数据不能转换为其他任何基本数据类型。
在这里插入图片描述

9、为什么8位的double的范围比8位的long的大

答 : double在计算机中的存储方法:无论是单精度还是双精度在存储中都分为三个部分:
符号位(Sign) : 0代表正,1代表为负
指数位(Exponent):用于存储科学计数法中的指数数据,并且采用移位存储
尾数部分(Mantissa):尾数部分正是它不同于long long的存储方法,使得它虽然只有64位但是可以比同样是64位的long long 类型取值范围大很多。
对于long: 64位的范围应该是[-2^63 ,2^63],既-9223372036854775808~9223372036854775807。 它的存储方法就是按位存储。有符号位就有一位符号位,没有符号位就64位全部来存储这个数。
**另PS:在栈中,只保存有基本类型的变量和对象引用。引用所指向的对象保存在堆中。(引用可能为Null值,即不指向任何对象)
**

**10.【扩展】父子类中含有成员变量、静态成员变量、非静态语句块、静态语句块、构造方法、请问创建一个父类对象和一个子类对象时,成员变量、静态成员变量、非静态语句块、静态语句块、构造方法的执行顺序?

执行顺序:
1、执行了父类静态代码块
2、执行了子类静态代码块
3、执行了父类非静态语句块或成员变量(二者的先后由位置先后决定)
4、执行了父类构造方法
5、执行了子类非静态语句块或成员变量(二者的先后由位置先后决定)
6、执行了子类构造方法

静态语句块;
非静态语句块或成员变量(二者的先后由位置先后决定);
构造方法

注意:
静态代码块只执行一次;
非静态代码块每次new时都执行;

1、如果一个类的成员变量在声明时就进行初始化处理, 则先执行成员变量的初始化,然后调用构造方法创建实例
2、如果一个类中有静态语句块,则在加载到jvm时(不一定创建实例),先执行静态语句块,(并且只执行一次),再执行成员变量的初始化,最后调用构造方法创建实例
3、如果一个类中有非静态语句块,则非静态语句块在类的成员变量初始化之后,构造方法执行之前进行执行。(并且每次使用new创建实例对象时都会执行一次)

11.int i = 0; i = i++; 请问变量i的值是多少?

i++与i–等都有有两种值:整体表达式的值;表达式中的变量自己的值;结论:例如i++和++i:无论是先增还是后增,变量i的值总是+1的;整体表达式的值是先增+1;后增的不+1;
所以i等于i++中,i++整体表达式后增的,不加1为0;i的值是1;但是是把i++整体表达式赋值给i,所以i的值为0

12.如何不使用第三个临时变量,交换两个整型变量的值?

异或方法:
x^=y;//x先存x和y两者的信息
y^=x;//保持x不变,利用x异或反转y的原始值使其等于x的原始值
x^=y;//保持y不变,利用x异或反转y的原始值使其等于y的原始值

算术方法:原理是:把a、b看做数轴上的点,围绕两点间的距离来进行计算。
int a,b;
a=10;b=12;
a=b-a; //a=2;b=12 求出ab两点的距离,并且将其保存在a中
b=b-a; //a=2;b=10 求出a到原点的距离(b到原点的距离与ab两点距离之差),并且将其保存在b中
a=b+a; //a=10;b=10 求出b到原点的距离(a到原点距离与ab两点距离之和),并且将其保存在a中

13.计算机中的所有的数(正数、负数、0)都是以补码的形式存在的。位运算是在补码的基础上进行的。★★★★★

计算机里的数都是补码形式,因为CPU只会做加法(还有移位),数的补码形式就可以用加法实现减法运算,进而以加法完成所有的运算。

14.原码、反码、补码

原码
计算机要进行计算就必须存储数值,最简单的方法就是用机器码作为我们的真值,比如一个 8 位的存储单元可以存储 00000000 ~ 11111111 共 256 种数字,真值从 0 ~ 255,但是这样设计显然意义不大,因为我们需要计算负数。为了引入负数,所以设计出了原码:用存储单元的第一位表示符号,1 位负,0 为正,后面的位表示真值的绝对值。同样以 8 位存储单元位例,在用原码的方式下我们依然可以表示 256 个数,从 11111111 ~ 01111111,真值范围为 -127 ~ 127,可能你发现真值一共只有255 个,因为 10000000 和 00000000 表示的都是 0。
反码
反码的定义是:如果是正数则保持不变,如果是负数,则除符号位之外按位取反
补码
补码的定义就是:正数和 0 的补码不变,负数的补码是其对应的正数按位取反再 +1。

15.for(;;){}和while(true){}这两个死循环哪个执行效率高?

认为for(;?,效率更高。原因for循环中什么都没有执行,所以耗费的内存空间要小一些。while循环中还要每次都执行true语句,要耗费一定的内存。
for( ; ; ) 死循环里面的两个 ; ; 语句代表空语句,编译器一般会优化掉他们,直接进入循环体。
while ( true ) 死循环里的true 被看成表达式,每次循环一次都要判断表达式是否为真,相对来说 for循环更高效一点。

编译后的代码:
在这里插入图片描述
一目了然,for (;;)指令少,不占用寄存器,而且没有判断跳转,比while (1)好。

16.break和continue关键字的区别?什么是位置标签?(break、continue和位置标签搭配可以达到goto的效果,非常非常非常不推荐使用)

break:用于跳出当前所在循环体,去执行循环后面的语句。
continue:用于结束本次循环,继续执行下一次循环。
1.break的适用范围:
只能用于switch或者是循环语句中。
2.break的作用:
(1)break用于switch语句中的作用是结束一个switch语句。
(2)break用于循环语句中的作用是结束当前所在的循环语句。
注意:break关键字可以用在switch–case的分支结构和循环结构。continue关键字只能用于循环中。
1.continue定义:
语句将控制权传递给它所在的封闭迭代语句的下一次迭代(跳出本次循环,执行下一次循环)。
2.continue的适用范围:
continue只能用于循环语句。
3.continue的作用:
continue的作用是跳过本次的循环体内容,继续下一次循环。(如果循环体内部continue之后没有内容,那么加上continue是没有意义的)。
4.continue要注意的事项:
(1)在一种情况下(顺序执行),continue后面不能跟有其他语句,因为是永远都无法执行到的,所以编译会报错,Java是不允许出现废话的。
(2)continue也可以配合标记使用。
(3)如果continue出现在循环的末尾(最后一条语句),那么可以省略。

17.形参和实参?

形参方法定义时给定的参数列表;实参:方法调用时,主方法传递给被调用的子方法的参数;形参与实参顺序,类型,个数一一对应
在这里插入图片描述
形参:方法定义时给定的参数列表。目的是用来接收调用函数时传递的参数。
形参变量只有在被调用时才分配内存单元,调用结束即刻释放锁分配的内存单元。
实参:方法调用时,主方法传递给子方法的参数。具有确定的值。
形参和实参的功能是做数据传送,发生函数调用时,主调函数把实参的值传送给被调函数的形参,从而实现主调函数向被调函数的数据传送。
函数调用时发生的数据传送是单向的。只能把实参的值传送给形参。
形参和实参要一一对应(个数、类型和顺序要对应)

18. void类型的返回方法是否可以使用return关键字?

Java中的函数除了构造方法没有返回类型之外,其他的方法都是又返回类型的,例如显示的标注了int、String、boolean等,注意标注了void不代表没有返回类型,只是返回类型为空,这一点要区别于类的构造方法,构造方法是没有写明返回类型关键字的。有时候需要在函数内部强行终止函数继续运行下面的语句,即终止运行方法,这时就需要用到 return语句。格式:return ;

1. 我们在void返回类型的方法中有时看得到return关键字,有时又看不到,这分两种情况。

1.return在方法体的最后一行
public void method(){
//…
//…
//…
return;
}
最后一行的return可写可不写,如果写就写成“return;”,返回类型为空。
2.return在方法体的中间
public void method(){
//…
//…
return;
//…
}
在中间的情况表示退出方法的意思,后面的代码就不执行了。

19.java中实参和形参的参数值的传递方式?java传值的方式? java是如何传值的?

在这里插入图片描述
按值传参,实参传递给形参是实参值的拷贝,形参值的改变不会影响实参。
在这里插入图片描述
按引用(地址)传参,实参传递给形参的是实参的地址引用,形参值的改变会影响实参。
在这里插入图片描述

20.什么是方法的重载?重载的条件?重载的调用方式?什么是方法的重写?重写的条件? 二者的异同点?

方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。方法重载通常用于创建完成一组任务相似但参数的类型或参数的个数或参数的顺序不同的方法。 [1] Java的方法重载,就是在类中可以创建多个方法,它们可以有相同的名字,但必须具有不同的参数,即或者是参数的个数不同,或者是参数的类型不同。调用方法时通过传递给它们的不同个数和类型的参数,以及传入参数的顺序来决定具体使用哪个方法
Java的函数重载必须满足的条件
1.函数名相同
2.参数个数不同或者参数类型不同
3.函数重载和返回值类型无关,方法的返回类型、修饰符可以相同,也可不同。

Java的方法重载和方法的调用

重载的调用方式
在这里插入图片描述

方法的重写
在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
在这里插入图片描述

重写的条件
重写规则之一:重写方法不能比被重写方法限制有更严格的访问级别。(但是可以更广泛,比如父类方法是包访问权限,子类的重写方法是public访问权限。)
重写规则之二:参数列表必须与被重写方法的相同。
重写规则之三:返回类型必须与被重写方法的返回类型相同。
重写规则之四:重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常。(例:父类抛出了检查异常Exception,子类抛出的IOException是Exception的子类,也即是比被重写的方法抛出了更有限的异常,这是可以的。如果反过来,父类抛出IOException,子类抛出更为宽泛的Exception,那么不会通过编译的。
注意:这种限制只是针对检查异常,至于运行时异常RuntimeException及其子类不再这个限制之中。)
重写规则之五:不能重写被标识为final的方法。
重写规则之六:如果一个方法不能被继承,则不能重写它。(父类的private修饰的方法)

重写与重载的区别
override重写
重写是子类对父类的方法进行重新实现
overload重载
重载是同一个类中几个相同名称的方法
重写的方法名称、返回类型、参数列表必须完全相同,异常不能更广泛,访问修饰符不能更高
重载的方法名称必须相同,参数列表必须不同,返回类型、异常、访问修饰符可以不同
方法的重写和重载具有以下相同点:
1.都要求方法同名
2.都可以用于抽象方法和非抽象方法之间

21.什么是变长参数(jdk1.5+?)?变长参数和重载的关系?

jdk1.5的新特性之一 ——————变长参数
变长参数只能是形参里列表的最后一个,且一个方法至多只能使用一个变长参数
可变参数的格式:

1.数据类型… 变量名

变长参数本质就是一个数组,与数组的差别在于1、可变参数是兼容数组类参数的,但是数组类参数却无法兼容可变参数。2、出现的位置不同:数组形式的形参可以出现形参的任意位置,但是可变长度的形参只能出现在形参列表的最后。3、数量不同:数组形式的形参可以有任意多个,但是可变长度的形参最多只能有一个。
变长参数在使用实参传值时可以是0个1个多个
变长参数可以构成重载;重载时优先调用不使用变长参数的方法;重载调用时优先级比较低,会优先调用相同参数列表中不含变长参数的方法。

21.什么是不规则二维数组?如何进行遍历?

非矩阵行的二维数组,每行所定义的列的个数可以不同
在这里插入图片描述
String类
以\0结束 底层也是一个字符数组
字符串特性:固定长度,默认值为null 参考jdk的API
Stringbuilder是变长的默认长度16个字节,可以频繁的进行字符串的链接,存放在堆中。
StringBuffer 属于线程安全类。

22.String类在内存中的存储方式?

String类的内存分配
  首先说一下Java内存分配。物理的内存是线性结构,并不存在拥有不同功能的不同区域,编译器(或者JVM)为了更高效地处理数据,会用不同的算法把内存分为各种区域,不同的区域拥有各自的特性,Java中,内存可以分为栈,堆,静态域和常量池等。

不同内存区域的功能和特点:

栈区:存放局部变量(变量名,对象的引用等)特点:内存随着函数的调用而开辟,随着函数调用结束而释放。

堆区:存放对象(也就是new出来的东西)特点:可以跨函数使用,每个对象有自己对应的存储空间。

静态域:存放在对象中用static定义的静态成员。

常量池:存放常量。(常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。)

定义String的方法:

1,String str1 = “hello”;

2,String str2 = new String(“hello”);

第一种方法:引用str1被存放在栈区,字符串常量"hello"被存放在常量池,引用str1指向了常量池中的"hello"(str1中的存放了常量池中"hello"的地址)。

第二种方法:引用str2被存放在栈区,同时在堆区开辟一块内存用于存放一个新的String类型对象。(同上,str2指向了堆区新开辟的String类型的对象)

如图:
在这里插入图片描述
这两种方式的区别:

第一种:常量池的字符串常量,不能重复出现,也就是说,在定义多个常量时,编译器先去常量池查找该常量是否已经存在,如果不存在,则在常量池创建一个新的字符串常量;如果该常量已经存在,那么新创建的String类型引用指向常量池中已经存在的值相同的字符串常量,也就是说这是不在常量池开辟新的内存。

String str1 = “hello”;

String str2 = “hello”;

如图1
在这里插入图片描述
第二种:在堆中创建新的内存空间,不考虑该String类型对象的值是否已经存在。换句话说:不管它的 只是多少,第二种方法的这个操作已经会产生的结果是:在堆区开辟一块新的内存,用来存放新定义的String类型的对象。

String str1 = new String(“hello”);

String str2 = new String(“hello”);

如图2
在这里插入图片描述
java把内存分为两种,一种是栈内存,一种是堆内存。
在函数中定义的基本类型变量和对象的引用变量都是在函数的栈内存中分配;
堆内存用来存放由new 创建的对象和数组以及对象的实例变量。
String是一个特殊的包装类,可以通过两种方式创建,String s = new String(“abc”); Stirng s = “abc”;

23.String str1 = new String(“小明”); 该行代码执行之后在内存中创建了几个对象?

会首先执行()中的小明,即首先将“小明”放到在字符串常量池(栈)中,然后jvm运行到new String时又会在堆内存中开辟一块新的内存空间,并把字符串常量池里面的“小明”复制到堆内存中,这样就是创建了两个对象,如果常量池中的“小明”没有被引用就会被垃圾回收机制清除掉。

24. == 和 equals的异同点?

1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

25.面向对象的核心思想?你如何理解面向对象?什么是面向对象的编程?什么是抽象?什么是封装?什么是继承?什么是多态?

抽象、封装、继承、多态
面向对象:是一种对现实世界理解和抽象的方法。
面向过程:是一种以过程为中心的编程思想。
面向对象的编程方式使得每一个类只做一件事,面向过程会让一个类越来越全能,做所有的事情。
抽象:把一类的共性抽取出来,从个体到整体抽象共性。
封装:把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者操作,对不可信的信息进行隐藏。
继承:可以使用现有类的所有功能,并在无需重新编写原来类的情况下对这些功能进行扩展。通过扩展的类成为子类或派生类,被继承的成为基类、父类或超类。
多态:子类行为和父类行为不一样。实现多态有两种方式:重写和重载。重写是在运行时决定的,重载是在编译时局决定的。
在这里插入图片描述
什么是抽象 : 抽取关键相关特性(属性和方法)构成对象,用程序的方法逻辑和数据结构 属性模拟现实的世界对象
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

26.抽象封装的软件工程的原则:高内聚低耦合;

数据抽象是依赖于接口和实现分离的编程技术。使用接口的用户(程序员)不需要关心具体这个实现的细节,只需要知道怎么样去使用即可,具体的这个实现的具体内容可以通过猜测大致的知道就行。
封装是将低级的元素组成起来形成高层次的实体的一种技术,比如常规的函数!函数内部隐藏了具体要执行的代码的细节。
高内聚指模块内部元素之间高度紧密联系,为了模块的功能实现而工作和合作。
低耦合是指不同的模块之间尽可能的相对独立的运行,尽量减少牵扯,在后续修改或者扩展的时候更方便和容易。
耦合性:块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块间联系越紧密耦合性就越强,模块的独立性就越差。模块间的耦合性高低取决于模块间接口的复杂性、调用的方式以及传递的信息。
耦合性(低–>高):无直接耦合、数据耦合、标记耦合、控制耦合、公共耦合、内容耦合。
数据耦合:两个模块之间具有调用关系,传递的是简单的数据值
标记耦合:两个模块之间传递的是数据结构的地址
控制耦合:两个模块之间传递的是控制变量,通过控制变量选择执行某一功能
公共耦合:公共数据环境相互作用的那些模块间的耦合。随着耦合模块的增加而增加。
内容耦合:一个模块直接使用另一个模块的内部数据,或直接转入另一模块的内部。
内聚性:块内联系。值模块的功能强度的度量。即一个模块内部各个元素彼此结合的紧密程度的度量。若联系越紧密,则内聚性越高。
内聚性(低–>高):偶然内聚、逻辑内聚、时间内聚、通信内聚、顺序内聚、功能内聚。
偶然内聚:模块内元素之间没有任何联系。
逻辑内聚:模块内执行几个逻辑上相似的功能。
时间内聚:同时执行的动作组合在一起形成的模块
通信内聚:模块内所有处理元素都在一个数据结构上操作,或是使用相同的输入数据或产生相同的输出数据。
顺序内聚:模块内完成同一功能必须顺序执行,前一个功能的输出数据是下一个功能的输入数据。
功能内聚:模块内所有元素共同完成同一个功能,缺一不可。

27.局部变量和成员变量的区别?(局部变量覆盖成员变量,依据范围最小优先、就近原则)

在这里插入图片描述

28.构造方法的执行流程? 父类和子类构造方法的关系?

构造方法的执行流程
一、先执行内部静态对象的构造方法,如果有多个按定义的先后顺序执行;静态对象在构造的时候也是也先执行其内部的静态对象。

二、再调用父类的构造方法(父类还有父类的话,从最开始的基类开始调用),如果没有明显指定调用父类自定义的构造方法,那么编译器会调用默认的父类构造方法super()。但是如果要调用父类自定义的构造方法,要在子类的构造方法中明确指定。

三、按声明顺序将成员引用对象变量初始化。

四、最后调用自身的构造方法。
关系:java继承中,子类是不会继承父类的构造函数,只是必须调用(隐式或显式),因为子类是基于父类产生的。子类不能继承父类的显示定义的构造方法,若想要继承父类的构造方法,需要通过覆盖该构造方法,并在方法中通过super调用父类的该构造方法的方式来继承。

1、父类中没有显式定义任何构造方法,此时父类中实际有一个默认的无参构造方法。这时,在子类中显式定义任何构造方法时,可以不用使用super调用父类的默认方法。
2、分类中显式定义了默认的无参构造方法,那么子类可以定义任意的构造方法,而不必使用super调用父类的构造方法。
3、父类中显式定义了构造方法,却没有显式定义默认的无参数构造方法,那么子类定义任何构造方法中都需要通过super调用父类的构造方法。

29.什么是继承?java的继承是单继承?java能不能实现多继承?

继承(英语:inheritance)是面向对象软件技术当中的一个概念。如果一个类别A“继承自”另一个类别B,就把这个A称为“B的子类别”,而把B称为“A的父类别”也可以称“B是A的超类”。继承可以使得子类别具有父类别的各种属性和方法,而不需要再次编写相同的代码。在令子类别继承父类别的同时,可以重新定义某些属性,并重写某些方法,即覆盖父类别的原有属性和方法,使其获得与父类别不同的功能。另外,为子类别追加新的属性和方法也是常见的做法。 一般静态的面向对象编程语言,继承属于静态的,意即在子类别的行为在编译期就已经决定,无法在执行期扩充。
那么如何使用继承呢?用extends关键字来继承父类。
java的继承是单继承若为多继承,那么当多个父类中有重复的属性或者方法时,子类的调用结果会含糊不清,因此用了单继承。
Java可以实现多继承,有三种方式:
多层继承我们知道,如果要直接继承类,子类不可直接多继承,但可通过多层继承实现多继承。但多层继承一般建议不超过三次,且代码较冗余。
内部类成员内部类可直接实现多继承。
接口第三种实现多继承的方法是接口,在同时可用内部类和接口时,优先使用接口。因内部类需要应用于继承关系,接口可用于继承也可用于其他,比较灵活。

30.什么是多态?多态体现在那些方面?(多态体现在:一是:父类指代子类(溯型);二是:重写)什么是重写?什么是溯型?

多态:多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。
(多态就是指程序中 定义的引用变量 所指向的具体类型和 通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。)
重写 :在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
上溯造型:(向上转型)子类转换为父类,自动转换;前提:具有继承或实现关系;向上转换损失了子类新扩展的属性和方法,仅可以使用从父类中继承的属性和方法。
下溯造型:(向下转型):强制转换;将父类对象显示的转换成子类类型。曾经向上转换过的对象,才能再向下转换。对象不允许不经过上溯造型而直接下溯造型。

31.构成重写的条件?

方法重写的条件
1、发生继承关系
2、发生实现关系
3、父类不能满足子类的需求
4、子类重写父类的方法
什么样的情况会发生重写
1、发生继承
2、方法名相同
3、参数列表要一摸一样(顺序,个数,类型)
4、子类的引用类型返回值 小于等于 父类的引用类型返回值
5、若父类的返回值类型是基本数据类型,则子类要一摸一样
6、子类的修饰符 要大于等于 父类的修饰符
7、子类抛出的异常 要小于等于 父类抛出的异常
8、不能重写被标识为final的方法。
9、静态方法不能被重写。

32.this和super关键字的区别?

一、Java当中this和super的区别
1.属性的区别:
(1)this访问本类中的属性,如果本类没有这个属性则访问父类中的属性。
(2)super访问父类中的属性。
2.方法的区别:
(1)this访问本类中的方法,如果本类没有这个方法则访问父类中的方法。
(2)super访问父类中的方法。
3.构造的区别:
(1)this调用本类构造构造,必须放在构造方法的首行。
(2)super调用父类构造,必须放在子类构造方法首行。
(3)其他区别:this表示当前对象。super不能表示当前对象

二、this. 变量和super.变量
(1)this.变量:调用的当前对象的变量;
(2)super.变量:直接调用的是父类中的变量。

三、this(参数)和super(参数)方法
(1)this(参数):调用(转发)的是当前类中的构造器;
(2)super(参数):用于确认要使用父类中的哪一个构造器。

四、注意点:
(1)在对拥有父类的子类进行初始化时,父类的构造方法也会执行,且优先于子类的构造函数执行;因为每一个子类的构造函数中的第一行都有一条默认的隐式语句super();
(2)this() 和super()都只能写在构造函数的第一行;
(3)this() 和super() 不能存在于同一个构造函数中。
1)this()和super()都必须写在构造函数的第一行;
2)this()语句调用的是当前类的另一个构造函数而这个另一个构造函数中必然有一个父类的构造器,再使用super()又调用一次父类的构造器, 就相当于调用了两次父类的构造器,编译器不会通过;
(4)this和super不能用于static修饰的变量,方法,代码块;因为this和super都是指的是对象(实例)
在这里插入图片描述
四大关键字
static:可以修饰的对象:方法、属性、语句块。
静态方法只能调用静态的属性和方法。静态方法中不能使用this关键字。非静态的方法可以调用所有的。静态语句块在类加载时值执行一次,一般用于初始化。
final:可以修饰的对象:类、变量、方法
类是终结类,不能被继承。方法属于终结方法,不能被重写。修饰的常量,一旦初始化赋值后,不能再修改。
按值传参的类型,不能修改值。常量一旦初始化被赋值之后不允许修改。
按引用传参的类型,不能修改地址引用,可以修改内容。
搭配static关键字构成静态常量 接口里面的常量都是静态常量
abstract:可以修饰的对象:类、方法
抽象类不能被new创建实例对象–因为含有抽象部分,无法直接分配地址空间大小。
抽象方法中没有方法体,子类需要通过重写来实现父类抽象方法的方法体。
含有抽象方法的类一定是抽象类,抽象类不一定含有抽象方法。
interface:接口是一组抽象行为的集合体
接口的多继承主要体现在两个方面:
一、类和接口的多继承 可以使用 类 implements 接口,…
二、接口与接口直接的多继承,可以使用 接口 extends 接口,…
接口中的变量都是公共静态常量,其中public、static、final可以部分省略或全部省略
接口中的方法都是公共抽象方法,其中public、abstract可以部分或全部省略。

33.接口和抽象类的异同点?是否了解Default关键字?

抽象类与接口异同点:
  抽象类:一般用于描述一个体系单元,将一组共性内容进行抽取。特点:可以在类中定义抽象内容让子类实现,可以定义非抽象内容让子类直接使用。它里面定义的都是一些体系中的基本内容。
  接口: 一般用于定义对象的扩展功能,是在继承之外还需这个对象具备的一些功能。

抽象类和接口的共性:
  都是不断向上抽取的结果。

抽象类和接口的区别:
1:抽象类只能被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2:抽象类中可以定义非抽象方法,子类可以直接继承使用。
接口中都有抽象方法,需要子类去实现。
3:抽象类使用的是 is a 关系。
接口使用的 like a 关系。
4:抽象类的成员修饰符可以自定义。
接口中的成员修饰符是固定的。全都是public的
Default关键字
Default关键字是java8中的一种新添加的 接口里面都是抽象方法,
在switch语句中使用default。如果case里的值与switch里面的key没有匹配就执行default。
在定义接口的时候使用default来修饰具体的方法。JDK8 中为了加强接口的能力,是的接口可以存在具体的方法,前提是方法需要被default 或 static 关键字所修饰。这样做的好处是接口的每个实现类如果都像想要实现相同的功能,就不需要写重复代码,而是在接口进行定义即可。默认方法在子类也可以被重写。
default 作为访问限制符。在成员函数定义时,内衣加访问限制符的函数,其访问等级为default。
|位置 | private | default | protected | public |
|–|–|–|–|–|
| 同一个类 |是 |是 | 是 |是 |
|同一个包内的类 | 否 | 是| 是| 是|
|不同包内的子类 | 否 | 否 | 是 | 是 |
|不同包并且不是子类 |否 | 否 | 否 | 是 |

34.匿名内部类?事件处理?委托?

匿名内部类:匿名内部类就是一个没有显式的名字的内部类,匿名内部类会隐式的继承一个类或者实现一个接口,或者说,匿名内部类是一个继承了该类或者实现了该接口的子类匿名对象。
匿名内部类详解

委派:一个对象请求另一个对象的功能,捕获一个操作并将其发送到另一个对象。

事件处理机制深入理解:
编写事件处理类(事件监听者)
根据需求给事件处理类实现监听接口
在事件处理类中重写(实现)其事件处理函数
在事件源类中指定该事件的监听器(响应者)是谁,即注册监听。
java事件处理的三种方式:

使用接口
定义一个类,使用接口。
使用匿名内部类

java中采用委托机制处理事件,java中的事件是分类的(例如:鼠标时间、窗体事件、键盘事件等)。
java中一个类要监听某个事件,则必须实现相应的事件监听接口,在实现监听接口类中,要重写处理函数。事件源中需要注册事件监听类,否则事件监听类接受不到事件源发生的事件。

35.异常的分类?异常和错误的区别?

在这里插入图片描述
非检查异常(unckecked exception):Error 和 RuntimeException 以及他们的子类。javac在编译时,不会提示和发现这样的异常,不要求在程序处理这些异常。所以如果愿意,我们可以编写代码处理(使用try…catch…finally)这样的异常,也可以不处理。对于这些异常,我们应该修正代码,而不是去通过异常处理器处理 。这样的异常发生的原因多半是代码写的有问题。如除0错误ArithmeticException,错误的强制类型转换错误ClassCastException,数组索引越界ArrayIndexOutOfBoundsException,使用了空对象NullPointerException等等。

检查异常(checked exception):除了Error 和 RuntimeException的其它异常。javac强制要求程序员为这样的异常做预备处理工作(使用try…catch…finally或者throws)。在方法中要么用try-catch语句捕获它并处理,要么用throws子句声明抛出它,否则编译不会通过。这样的异常一般是由程序的运行环境导致的。因为程序可能被运行在各种未知的环境下,而程序员无法干预用户如何使用他编写的程序,于是程序员就应该为这样的异常时刻准备着。如SQLException , IOException,ClassNotFoundException 等。
异常和错误的区别。

异常: 在Java中程序的错误主要是语法错误和语义错误,一个程序在编译和运行时出现的错误我们统一称之为异常,它是VM(虚拟机)通知你的一种方式,通过这种方式,VM让你知道,
你(开发人员)已经犯了个错误,现在有一个机会来修改它。Java中使用异常类来表示异常,不同的异常类代表了不同的异常。但是在Java中所有的异常都有一个基类,叫做Exception。

错误:它指的是一个合理的应用程序不能截获的严重的问题。大多数都是反常的情况。错误是VM的一个故障(虽然它可以是任何系统级的服务)。所以,错误是很难处理的,
一般的开发人员是无法处理这些错误的。比如内存溢出;和异常一样,在Java中用错误类来表示错误,不同的错误类代表了不同的错误。

但是在Java中所有的错误都有一个基类,叫做Error。

综上,我们可以知道异常和错误最本质的区别就是异常能被开发人员处理而错误是系统本来自带的,一般无法处理也不需要我们程序员来处理。

异常的分类
在Java中异常分为两大类:编译异常和运行异常
运行异常即是RuntimeException;其余的全部为编译异常

JAVA中的异常体系

在Java中异常Exception和错误Error有个共同的父类Throwable.

三、RuntimeException几个子类的具体介绍

1、 java.lang.ArrayIndexOutOfBoundsException

数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。

2、java.lang.ArithmeticException

算术条件异常。譬如:整数除零等。

3、java.lang.NullPointerException

空指针异常。当应用试图在要求使用对象的地方使用了null时,抛出该异常。譬如:调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等

4、java.lang.ClassNotFoundException

找不到类异常。当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常。

36.异常的处理机制?finally语句块的特点?

java默认处理机制:
1抛出异常
2终止程序
异常处理程序机制:
1抛出异常
2try-catch-finally 捕获和处理异常
当Java程序运行到某个方法发生异常时,产生一个对应异常类对象,包含异常事件类型,发生异常是应用程序的状态,和调用过程等信息,然后抛出,运行系统开始查找有没又匹配异常处理程序,么有,就中断程序,有就将控制权交个程序处理程序,处理异常。

finally一般是做一些善后清理工作,所以可以将回收代码放入finally语句块中。而java的垃圾回收机制其实不会回收任何物理资源,在java程序中,通常使用finally来回收物理资源,如果文件流、连接池、新实例等等,finally块的作用就是为了保证无论出现什么情况,finally块里的代码一定会被执行。

异常的处理机制:try-catch-finally、throws。
try-catch-finally:多个catch分支范围从小到大,finally总会被执行,无论是否发生异常。使用或连接多个异常类型时,彼此之间不能有包含关系。
throws:谁调用谁负责处理异常,如果一直向上抛异常,则最终由jvm进行异常处理。
throw:人为抛出一个异常。
自定义异常:通过继承Exception及其子类实现。可以使用多态进行扩展。
finally语句块的特点:
被finally控制的与具体一定会执行。特殊情况是在执行到finally之前jvm退出了(System.exit(0) ; )。所以通常在程序中为了保证哞资源一定会被释放,一般在finally语句块中释放资源。

37.什么是包装类?什么是装箱?什么是拆箱?

java中的数据类型int,double等不是对象,无法通过向上转型获取到Object提供的方法,而像String却可以,只因为String是一个对象而不是一个类型。基本数据类型由于这样的特性,导致无法参与转型,泛型,反射等过程。为了弥补这个缺陷,java提供了包装类。
 包装类顾名思义就是将基本的数据类型以及一些辅助方法包装到类中

装箱:

将基本数据类型封装为包装类对象,利用每一个包装类提供的构造方法实现装箱操作。
拆箱:

将包装类中包装的基本数据类型数据取出。
JDK1.5之后提供自动拆装箱。

Integer i = 10; //装箱
int n = i; //拆箱
在这里插入图片描述

38.为什么要有包装类?包装类存在的价值?java中那些地方必须使用包装类?Synchronize(此处必须是包装类){}、泛型、集合中存储的是包装类…

包装类有三个用法 一个实现基本类型之间的转换 二是便于函数传值 三就是在一些地方要用到Object的时候方便将基本数据类型装换。
java包装类将基本数据类型的值包装到对象中,对基本数据类型的操作变为了对对象进行操作,从而使基本值能够包含在为对象保留的操作中。更加方便类型的转换,如常见的integer向字符串的转换。八种基本类型不符合OO原则(面向对象编程的原则)

工具类:
包装类:八种基本类型纳入OO体系。包装类主要针对八种基本类型。八种基本类型的包装类,对象性包装类、数值型包装类
object类:根类、祖宗类。HashCode,toString,equals
Sting类:String类是对象类型,但是方法调用时按值传参。

39.== 和 equals的区别?Object中的equals方法的用法?

在Object这个类里面提供的Equals()方法默认的实现是比较当前对象的引用和你要比较的那个引用它们指向的是否是同一个对象,即和“c1c2”这种写法是一样的,“c1.equals(c2)”与“c1c2”是完全等价的。因此直接使用继承下来的equals()方法也是无法直接比较两个对象的内容是否相同的,为此,我们必须得重写equals()方法,改变这个方法默认的实现。

40.finally和return的用法(编程题)

finally是在retrun语句执行后,return返回之前执行的,也就是说finally必执行(当然是建立在try执行的基础上)
finally中修改的基本类型没有return是不影响返回结果的,有了retrun才会影响
finally中修改list ,map,set引用类型时,就算没有return,也是是影响返回结果的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值