Java面试题大全之Java基础面试题系列四(每天巩固一点点)
发布于 2021-09-07 11:03 ,所属分类:2021面试经验技巧分享
31、String str = "i" 与 String str = new String("i") 一样吗?
不一样,因为内存的分配方式不一样。String str = "i" 的方式,Java 虚拟机会将其分配到常量池中;而 String str = new String("i") 则会被分到堆内存中。
String s1 = "123";
String s2 = "123";
String s3 = new String( "123" );
String s4 = new String( "123" );
PrintStream out = System.out;
out.println( s1 == s2 ); //true
out.println( s1.equals( s2 ) ); //true
out.println( s1 == s3 ); //false
out.println( s1.equals( s3 ) ); //true
out.println( s3 == s4 ); //false
out.println( s3.equals( s4 ) ); //true
在执行 String s1 = "123" 的时候,JVM 会首先检查字符串常量池中是否已经存在该字符串对象,如果已经存在,那么就不会再创建了,直接返回该字符串在字符串常量池中的内存地址;如果该字符串还不存在字符串常量池中,那么就会在字符串常量池中创建该字符串对象,然后再返回。所以在执行 String s2 = "123" 的时候,因为字符串常量池中已经存在“123”字符串对象了,就不会在字符串常量池中再次创建了,所以栈内存中s1 和 s2 的内存地址都是指向 "123" 在字符串常量池中的位置,所以 s1 = s2 的运行结果为 true。而在执行 String s3 = new String("123") 的时候,JVM 会首先检查字符串常量池中是否已经存在“123”字符串,如果已经存在,则不会在字符串常量池中再创建了;如果不存在,则就会在字符串常量池中创建"123"字符串对象,然后再到堆内存中再创建一份字符串对象,把字符串常量池中的"123"字符串内容拷贝到内存中的字符串对象中,然后返回堆内存中该字符串的内存地址,即栈内存中存储的地址是堆内存中对象的内存地址。String s4 = new String("123")是在堆内存中又创建了一个对象,所以 s3 == s4运行的结果是 false。
32、如何将字符串反转?
使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。
33、String 类的常用方法都有那些?
indexOf():返回指定字符的索引。
charAt():返回指定索引处的字符。
replace():字符串替换。
trim():去除字符串两端空白。
split():分割字符串,返回一个分割后的字符串数组。
getBytes():返回字符串的 byte 类型数组。
length():返回字符串长度。
toLowerCase():将字符串转成小写字母。
toUpperCase():将字符串转成大写字符。
substring():截取字符串。
equals():字符串比较。
34、final 修饰 StringBuffer 后还可以 append 吗?
可以。final 修饰的是一个引用变量,那么这个引用始终只能指向这个对象,但是这个对象内部的属性是可以变化的。
35、final、finally、finalize 的区别?
final:用于声明属性、方法和类,分别表示属性不可变、方法不可覆盖、被其修饰的类不可继承;
finally:异常处理语句结构的一部分,表示总是执行;
finallize:Object类的一个方法,在垃圾回收时会调用被回收对象的finalize。
36、finally 块中的代码什么时候被执行?
在 Java 语言的异常处理中,finally 块的作用就是为了保证无论出现什么情况,finally 块里的代码一定会被执行。由于程序执行 return 就意味着结束对当前函数的调用并跳出这个函数体,因此任何语句要执行都只能在 return 前执行(除非碰到 exit 函数),因此 finally 块里的代码也是在 return 之前执行的。此外,如果 try-finally 或者 catch-finally 中都有 return,那么 finally 块中的 return将会覆盖别处的 return 语句,最终返回到调用者那里的是 finally 中 return 的值。程序在执行到 return 时会首先将返回值存储在一个指定的位置,其次去执行 finally块,最后再返回。因此,对基本数据类型,在 finally 块中改变 return 的值没有任何影响,直接覆盖掉;而对引用类型是有影响的,返回的是在 finally 对 前面 return 语句返回对象的修改值。
37、finally 是不是一定会被执行到?
不一定。下面列举两种执行不到的情况:
1、当程序进入 try 块之前就出现异常时,会直接结束,不会执行 finally 块中的代码;
2、当程序在 try 块中强制退出时也不会去执行 finally 块中的代码,比如在 try 块中执行exit 方法。
38、try-catch-finally 中那个部分可以省略?
catch 可以省略。try 只适合处理运行时异常,try+catch 适合处理运行时异常+普通异常。也就是说,如果你只用 try 去处理普通异常却不加以 catch 处理,编译是通不过的,因为编译器硬性规定,普通异常如果选择捕获,则必须用 catch 显示声明以便进一步处理。而运行时异常在编译时没有如此规定,所以 catch 可以省略,你加上 catch 编译器也觉得无可厚非。
39、Java类的初始化顺序?
静态变量和静态语句块优先于实例变量和普通语句块,静态变量和静态语句块的初始化顺序取决于它们在代码中的顺序。
存在继承的情况下,初始化顺序为:
1. 父类(静态变量、静态语句块)
2. 子类(静态变量、静态语句块)
3. 父类(实例变量、普通语句块)
4. 父类(构造函数)
5. 子类(实例变量、普通语句块)
6. 子类(构造函数)
40、Java 序列化中如果有些字段不想进行序列化,怎么办?
对于不想进行序列化的变量,使用 transient 关键字修饰。transient 关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化。当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。transient 只能修饰变量,不能修饰类和方法。
看完如果对你有帮助,感谢点击下面的一键三连支持下!
我的个人订阅号(大叔学Java/dashu_java),文章第一时间在gongzhong号发布,感兴趣的可以下,谢谢!
相关资源