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 );            //trueout.println( s1.equals( s2 ) );     //trueout.println( s1 == s3 );            //falseout.println( s1.equals( s3 ) );     //trueout.println( s3 == s4 );            //falseout.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号发布,感兴趣的可以下,谢谢!


相关资源