文章目录
- 一、Java基础
-
- 2.字符型常量和字符串常量的区别?
- 3.装箱与拆箱
- 4.成员变量与局部变量的区别有哪些
- 5.对象实例与对象引用有何不同?
- 6.一个类的构造方法的作用是什么? 若一个类没有声明构造方法,该程序能正确执行吗? 为什么?
- 7.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
- 8.值传递和引用传递的区别?
- 9.为什么 Java 中只有值传递?
- 10.Java序列化中如果有些字段不想进行序列化该怎么办?
- 11.获取键盘输入常用的两种方法
- 3.什么是Java程序的主类?应用程序和小程序的主类有何不同?
- 4.访问修饰符public,private,protected,以及不写(默认)时的区别?
- 5.float f=3.4;是否正确?
- 6.Java有没有goto?
- 7.(&和&&)的区别?
- 8.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
- 9.用最有效率的方法计算2乘以8?
- 10.什么是Java注释
- 11.Java有哪些数据类型
- 12.final 有什么用?
- 13.final finally finalize的区别
- 14.String str = "i" 和String str = new String("1")一样吗?
- 15.Java 中操作字符串都有哪些类?它们之间有什么区别?
- 16.Java中为什么要用 clone?
- 17.深克隆和浅克隆?
- 18.new一个对象的过程和clone一个对象的区别?
- 19.Java中实现多态的机制是什么?
- 20.谈谈你对多态的理解?
- 21.构造器(constructor)是否可被重写(override)?
- 23.是否可以继承String类?
- 24.String类的常用方法有哪些?
- 25.char型变量中能否能不能存储一个中文汉字,为什么?
- 26.this关键字的用法
- 27.super关键字的用法
- 28.this与super的区别
- 29.static存在的主要意义
- 30.static的独特之处
- 31.static应用场景
- 32.static注意事项
- 33.break ,continue ,return 的区别及作用
- 34.在Java中定义一个不做事且没有参数的构造方法的作用
- 35.构造方法有哪些特性?
- 36.静态变量和实例变量区别
- 37.静态方法和实例方法有何不同?
- 38.什么是方法的返回值?返回值的作用是什么?
- 39.什么是内部类?
- 40.内部类的分类有哪些
- 41.Java中异常分为哪些种类?/ Java中异常处理机制是什么?
- throw和throws的区别?
- 45.抽象类和接口(Java7)的区别
- 45.举例说明什么情况下会更倾向于使用抽象类而不是接口?
- 46.Java 8的接口新增了哪些特性?
- 47.重写和重载的区别
- 53.静态代理和动态代理
- 54.JDK动态代理和CGLIB动态代理的区别
- 55.Spring在选择用JDK还是CGLiB的依据:
- 25.Spring AOP 实现原理
- 11.Java 异常框架
- 56.自定义异常在生产中如何应用
- 57.怎样声明一个类不会被继承,什么场景下会用
- 59.什么是ForkJoin框架 适用场景
- instanceof 关键字的作用
- Object 有哪些常用方法?
- 获取一个类Class对象的方式有哪些?
- 类的加载过程
- 方法的参数传递机制
- 二、Java8新特性
- 三、Java IO
- 四、JavaWeb部分
- 五、Tomcat
一、Java基础
2.字符型常量和字符串常量的区别?
- 形式上: 字符常量是单引号引起的一个字符; 字符串常量是双引号引起的若干个字符
- 含义上: 字符常量相当于一个整型值( ASCII 值),可以参加表达式运算; 字符串常量代表一个地址值(该字符串在内存中存放位置)
- 占内存大小:字符常量只占 2 个字节; 字符串常量占若干个字节
3.装箱与拆箱
- 装箱:将基本数据类型转换为包装器类型。
- 拆箱:将包装类型转换为基本数据类型。
Java保留了基本数据类型(如int, double等),由于基本数据类型不是对象,因此无法直接将它们添加到集合中。
装箱与拆箱这种机制主要是为了使基本数据类型能够使用Java对象的一些特性,比如作为集合类(如List, Set)的元素,或者作为方法的参数和返回值等。
自动装箱
int num = 10;
Integer numInteger = num; // 自动装箱,将基本数据类型int转换为Integer对象
自动拆箱
Integer numInteger = 10;
int num = numInteger; // 自动拆箱,将Integer对象转换回基本数据类型int
实际应用
①集合类元素:由于基本数据类型不是对象,因此无法直接将它们添加到集合中。装箱机制允许我们将基本数据类型转换为它们的包装类对象,从而可以将它们存储在集合中。
List<Integer> list = new ArrayList<>();
list.add(5); // 自动装箱
int num = list.get(0); // 自动拆箱
②方法参数与返回值:当方法需要接收或返回基本数据类型的“对象化”版本时,可以使用装箱和拆箱。
// 一个接收Integer类型参数并返回Integer类型的方法
public Integer addTen(Integer num) {
return num + 10; // 这里实际上是拆箱成int进行加法运算,然后再装箱成Integer
}
public static void main(String[] args) {
// 调用方法时,自动装箱发生:将基本数据类型int转换为Integer对象
Integer result = addTen(5);
// 打印结果时,由于result是Integer类型,而System.out.println的参数是Object(通过自动拆箱和自动类型转换),
// 但这里不直接体现拆箱,因为println可以处理Object类型。但如果我们对result进行进一步操作,
// 比如赋值给int类型变量,就会看到拆箱操作。
System.out.println(result); // 输出:15
// 如果要将Integer转换为int并赋值给变量,则自动拆箱发生
int intResult = result; // 这里result被自动拆箱为int
System.out.println(intResult); // 输出:15
}
说说这 8 种基本数据类型对应的包装类型?
这八种基本类型都有对应的包装类分别为:Byte、Short、Character、Integer、Long、Float、Double、Boolean
那基本类型和包装类型有啥区别不?
Byte、Short、Character、Integer、Long、Float、Double、Boolean这些包装类的默认值是null,因为它们是对象类型。
基本类型是有默认值的:byte默认值0、short默认值0、char默认值’\u0000’、int默认值0、long默认值0L、float默认值0.0f、double默认值0.0d,boolean默认值false
在比较包装类型对象时,应使用equals方法而不是==
操作符
因为==
操作符比较的是对象的引用地址,而不是对象的值。
基本数据类型与包装类型的使用规范
== 与 equals
==
: 它的作用是判断两个对象的地址是不是相等。即,判断两个对象是不是同一个对象。(基本数据类型==
比较的是
值,引用数据类型==
比较的是内存地址)
equals() : 它的作用也是判断两个对象是否相等。但它一般有两种使用情况:
- 情况1:类没有覆盖 equals() 方法。则通过 equals() 比较该类的两个对象时,等价于通过“==”比较这两个对象。
- 情况2:类覆盖了 equals() 方法。一般,我们都覆盖 equals() 方法来两个对象的内容相等;若它们的内容相
等,则返回 true (即,认为这两个对象相等)
4.成员变量与局部变量的区别有哪些
- 从语法形式上看:成员变量是属于类的,而局部变量是在方法中定义的变量或是方法的参数;成员变量是对象的一部分,它随着对象的创建而存在,而局部变量随着方法的调用而自动消失。
- 成员变量如果没有被赋初值:则会被自动赋予类型的默认值(一种情况例外:被 final 修饰的成员变量必须显式地赋值),而局部变量则不会被自动赋值。
- 局部变量存储在栈里面,实例变量存储在堆里面,类变量存储在方法区里面(局长石堆)
5.对象实例与对象引用有何不同?
用new来创建对象实例(对象实例在堆内存中),对象引用指向对象实例(对象引用存放在栈内存中)。
一个对象引用可以指向 0 个或 1 个对象(一根绳子可以不系气球,也可以系一个气球);一个对象可以有 n 个引用指向它(可以用 n 条绳子系住一个气球)。
6.一个类的构造方法的作用是什么? 若一个类没有声明构造方法,该程序能正确执行吗? 为什么?
主要作用是完成对类对象的初始化工作。可以执行。因为一个类即使没有声明构造方法也会有默认的不带参数的构造方法。
7.在调用子类构造方法之前会先调用父类没有参数的构造方法,其目的是?
帮助子类完成初始化工作。
8.值传递和引用传递的区别?
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
swap(num1, num2);
System.out.println("num1 = " + num1);//10
System.out.println("num2 = " + num2);//20
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
public static void main(String[] args) {
int[] arr = {
1, 2, 3, 4, 5 };
System.out.println(arr[0]);//1
change(arr);
System.out.println(arr[0]);//0
}
public static void change(int[] array) {
// 将数组的第一个元素变为0
array[0] = 0;
}
千万不要以为传递的参数是值就是值传递,传递的是引用就是引用传递。也不要以为传递的参数是基本数据类型就是值传递,传递的是对象就是引用传递。
值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。
9.为什么 Java 中只有值传递?
值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
Java 程序设计语言总是采用按值调用。不论传递的参数类型是值类型还是引用类型,都会在调用栈上创建一个副本。不同的是,对于值类型来说,复制的就是整个原始值的复制。而对于引用类型来说,由于在调用栈中只存储对象的引用,因此复制的只是这个引用,而不是原始对象。
10.Java序列化中如果有些字段不想进行序列化该怎么办?
使用 transient 关键字修饰。transient 只能修饰变量,不能修饰类和方法
class Person implements Serializable {
private String name;
private transient int age; // 这个字段不会被序列化
private String address;
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + ", address='" + address + "'}";
}
}
11.获取键盘输入常用的两种方法
方法一:通过 Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
方法二:通过BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();
3.什么是Java程序的主类?应用程序和小程序的主类有何不同?
一个程序中可以有多个类,但只能有一个类是主类。在Java应用程序中,这个主类是指包含main()方法的类。
而在Java小程序中,这个主类是一个继承自系统类JApplet或Applet的子类。
应用程序的主类不一定要求是public类,但小程序的主类要求必须是public类。主类是Java程序执行的入口点。
4.访问修饰符public,private,protected,以及不写(默认)时的区别?
private只有当前类下可以访问,default是同包下的就可以访问,protected是子类也可以访问
(子类和父类不再同一个包中,所以你看看子类连default都访问不了,而同包中的类还可以访问)
①类的成员不写访问修饰时默认为default。
默认(default)对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。
②受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。
③Java中,外部类的修饰符只能是public或默认,类的成员(包括内部类)的修饰符可以是以上四种。
5.float f=3.4;是否正确?
数据类型转换参考:Day01_入门程序、常量、变量
不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F;。
6.Java有没有goto?
goto 是Java中的保留字,在目前版本的Java中没有使用。(Java关键字列表中有goto和const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)
7.(&和&&)的区别?
&运算符有两种用法:(1)按位与;(2)逻辑与。
&&运算符是短路与运算。
逻辑与跟短路与的差别是非常巨大的,虽然二者都要求运算符左右两端的布尔值都是true整个表达式的值才是true。
&&之所以称为短路运算是因为,如果&&左边的表达式的值是false,右边的表达式会被直接短路掉,不会进行运算。很多时候我们可能都需要用&&而不是&,例如在验证用户登录时判定用户名不是null而且不是空字符串,应当写为:username != null &&!username.equals(“”),二者的顺序不能交换,更不能用&运算符,因为第一个条件如果不成立,根本不能进行字符串的equals比较,否则会产生NullPointerException异常。注意:逻辑或运算符(|)和短路或运算符(||)的差别也是如此。
8.Math.round(11.5) 等于多少?Math.round(-11.5)等于多少?
Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四舍五入的原理是在参数上加0.5然后进行下取整。
9.用最有效率的方法计算2乘以8?
2 << 3,
因为将一个数左移n 位,就相当于乘以了2 的n 次方,那么,一个数乘以8 只要将其左移3 位
即可,而位运算cpu 直接支持的,效率最高,所以,2 乘以8 等於几的最效率的方法是2 << 3。
10.什么是Java注释
定义:用于解释说明程序的文字
Java注释的作用:
在程序中,尤其是复杂的程序中,适当地加入注释可以增加程序的可读性,有利于程序的修改、调试和交流。注释的内容在程序编译的时候会被忽视,不会产生目标代码,注释的部分不会对程序的执行结果产生任何影响。
11.Java有哪些数据类型
基本数据类型sout打印出来的是数值, 引用数据类型sout打印出来的是对象的地址值
其中八种基本数据类型:byte、short、char‐‐>int‐‐>long‐‐>float‐‐>double,boolean
12.final 有什么用?
用于修饰类、属性和方法;
被final修饰的类不可以被继承
被final修饰的方法不可以被重写
被final修饰的变量不可以被改变,被final修饰不可变的是变量的引用,而不是引用指向的内容,引用指向的内容是可以改变的
13.final finally finalize的区别
- final可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
- finally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码方法finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
- finalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调用System.gc()
方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。
14.String str = “i” 和String str = new String(“1”)一样吗?
不一样,因为内存的分配方式不一样。String str = "i"的方式JVM会将其分配到常量池中,而 String str = new String(“i”)JVM会将其分配到堆内存中。
15.Java 中操作字符串都有哪些类?它们之间有什么区别?
学习视频:第300集
操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会生成新的 String 对象,再将指针指向新的 String 对象,而 StringBuffer 、 StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
buffer听起来像“并发”
StringBuffer 和 StringBuilder 最大的区别在于,StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的,但 StringBuilder 的性能却高于 StringBuffer,所以在单线程环境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
16.Java中为什么要用 clone?
在实际编程过程中,我们常常要遇到这种情况:有一个对象 A,在某一时刻 A 中已经包含了一些有效值,此时可能会需要一个和 A 完全相同新对象 B,并且此后对 B 任何改动都不会影响到 A 中的值,也就是说,A 与 B 是两个独立的对象,但 B 的初始值是由 A 对象确定的。在 Java 语言中,用简单的赋值语句是不能满足这种需求的。要满足这种需求虽然有很多途径,但clone()方法是其中最简单,也是最高效的手段。
17.深克隆和浅克隆?
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于引用数据属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
18.new一个对象的过程和clone一个对象的区别?
new 操作符的本意是分配内存。程序执行到 new 操作符时,首先去看 new 操作符后面的类型,因为知道了类型,才能知道要分配多大的内存空间。分配完内存之后,再调用构造函数,填充对象的各个域,这一步叫做对象的初始化,构造方法返回后,一个对象创建完毕,可以把他的引用(地址)发布到外部,在外部就可以使用这个引用操纵这个对象。
clone 在第一步是和 new 相似的,都是分配内存,调用 clone 方法时,分配的内存和原对象(即调用 clone 方法的对象)相同,然后再使用原对象中对应的各个域,填充新对象的域,填充完成之后,clone方法返回,一个新的相同的对象被创建,同样可以把这个新对象的引用发布到外部。
19.Java中实现多态的机制是什么?
笔记链接:Day07_多态、final关键字、权限修饰符、内部类
接口
定义的引用变量
可以指向具体实现类
的实现方法
,该引用变量发出的方法调用到底是哪个类中实现的方法
,必须在程序运行期
间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源代码,就可以让引用变量绑定到各种不同的对象上
,从而导致该引用调用的具体方法随之改变,让程序可以选择多个运行状态,这就是多态性。
(大白话:Fu类接口定义了方法eat(),Zi类定义了实现方法eat(),Fu obj = new Zi();
那么obj.eat()的输出就是子类的eat()方法的输出,不用修改父类的eat()方法就可以输出新的内容)
20.谈谈你对多态的理解?
接口
定义的引用变量
可以指向具体实现类
的实现方法
,该引用变量发出的方法调用到底是哪个类中实现的方法
,必须在程序运行期
间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源代码,就可以让引用变量绑定到各种不同的对象上
,从而导致该引用调用的具体方法随之改变,让程序可以选择多个运行状态,这就是多态性。
(大白话:Fu类接口定义了方法eat(),Zi类定义了实现方法eat(),Fu obj = new Zi();
那么obj.eat()的输出就是子类的eat()方法的输出,不用修改父类的eat()方法就可以输出新的内容)
21.构造器(constructor)是否可被重写(override)?
答:构造器不能被继承,因此不能被重写,但可以被重载。
23.是否可以继承String类?
String 类是final类,不可以被继承。
补充:继承String本身就是一个错误的行为,对String类型最好的重用方式是关联关系(Has-A)和依赖关系(Use-A)而不是继承关系(Is-A)。
24.String类的常用方法有哪些?
•splt();字符串分割,返回分割后的字符串数组。
•getBytes();返回字符串byte类型数组。
•length();返回字符串长度。
•toLowerCase();将字符串转换为小写字母。
•toUpperCase();将字符串转换为大写字母。
•substring();字符串截取。
•equals();比较字符串是否相等。
•replace();字符串替换。
•indexof();返回指定字符的的索引。
•charAt();返回指定索引处的字符。
•trim();去除字符串两端空格。
25.char型变量中能否能不能存储一个中文汉字,为什么?
char可以存储一个中文汉字,因为Java中使用的编码是Unicode,一个char 类型占2个字节(16 比特),所以放一个中文是没问题的。
位 = 比特 = bit :信息的最小单位 ,等于0或1;
字节 = byte:可表示一个英文字母、一个数字或一个符号,不能表示一个汉字;
一个字节等于八比特,1 byte =8 bit
1Byte=8bit
1 KB = 1,024 Bytes
1 MB = 1,024 KB= 1024^2 Bytes
1 GB = 1,024 MB= 1024^2 KB= 1024^3 Bytes
GBK编码,一个汉字占两个字节。UTF-8编码,通常汉字占三个字节。
编码不同,汉字所占的字节也不同;通常一个汉字是2-4个字节。
一个char 类型占2个字节(16 比特),那么一个char是否能表示一个中文?
可以,完全可以,因为Java中采用的不是GBK、UTF-8编码,而是采用的Unicode编码,
Unicode是用16位表示的,char也是16位的,Unicode字符集有包含中文,所以放一个中文完全没有问题。
26.this关键字的用法
笔记链接:Day05_关键字【Static、this、super】
- 在本类的成员方法中,访问本类的成员变量。(形参与成员名字重名,用this来区分)
- 在本类的成员方法中,访问本类的另一个成员方法。
- 在本类的构造方法中,访问本类的另一个构造方法。
在第三种用法当中要注意:
A. this(…)调用也必须是构造方法的第一个语句,唯一一个。
B. super和this两种构造调用,不能同时使用。
1. 在本类的成员方法中,访问本类的成员变量。
public class Zi extends Fu {
int num = 20;
public void method() {
int num = 30;
System.out.println(num); // 30,局部变量
System.out.println(this.num); // 20,本类的成员变量
System.out.println(super.num); // 10,父类的成员变量
}
}
2. 在本类的成员方法中,访问本类的另一个成员方法。
public class Zi extends Fu {
public void methodA() {
System.out.println("AAA");
}
public void methodB() {
this.methodA(); //在本类的成员方法中,访问本类的另一个成员方法。
System.out.println("BBB");
}
}
3. 在本类的构造方法中,访问本类的另一个构造方法。
public class Zi extends Fu {
public Zi() {
this(123); // 本类的无参构造,调用本类的有参构造
}
public Zi(int n) {
this(1, 2); //在本类的构造方法中,访问本类的另一个构造方法。
}
public Zi(int n, int m) {
}
}
27.super关键字的用法
笔记链接:Day05_关键字【Static、this、super】
- 在子类的成员方法中,访问父类的成员变量。
- 在子类的成员方法中,访问父类的成员方法。
- 在子类的构造方法中,访问父类的构造方法。
public class Fu {
public Fu() {
System.out.println("父类的无参数构造方法!");
}
}
public class Zi extends Fu {
public Zi() {
super(); // 不管你写不写这行代码,系统都默认给你带上了
System.out.println("子类构造方法!");
}
}
public class Demo01Constructor {
public static void main(String[] args) {
Zi zi = new Zi();
}
}
输出:
父类的无参数构造方法!
子类构造方法!
28.this与super的区别
- super:它引用当前对象的直接父类中的成员
- this:它代表当前对象名(如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名)
- super()和this()类似,区别是,super()在子类中调用父类的构造方法,this()在本类内调用本类的其它构造方法。
- super()和this()均需放在构造方法内第一行,且只能使用一个。
- this()和super()都指的是对象,所以,均不可以在static环境中使用。包括:static变量,static方法,static语句块。
29.static存在的主要意义
①创建独立于具体对象的域变量或者方法。 以致于即使没有创建对象,也能使用属性和调用方法 !
②static块可以用来优化程序性能,因为:只会在类加载的时候执行一次。因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。
30.static的独特之处
独立于对象 且 优先于对象:
- 被static修饰的变量或者方法是独立于该类的任何对象,也就是说,这些变量和方法 不属于任何一个实例对象,而是被类的实例对象所共享。
- 被static修饰的变量或者方法是优先于对象存在的,也就是说当一个类加载完毕之后,即便没有创建对象,也可以去访问。
31.static应用场景
被static修饰的就是被整个类所共享的
- 修饰类【只能修饰内部类也就是静态内部类】
- 修饰成员方法
- 修饰成员变量
- 静态代码块
- 静态导包