Java面试~类

1.介绍一下Object类中的方法?

Class<?> getClass(); 返回该对象的运行时类;

boolean equals(Object obj); 判断指定对象与该对象是否相等;

int hashCode(); 返回该对象的hashCode值,默认情况下,是按照该对象的地址来计算。但很多类都重写了hashCode()方法,不再根据地址来计算返回值;

String toString(); 返回该对象的字符串表示;

clone(); 该方法用于帮助其他对象来实现自我克隆;

wait(); 控制线程的暂停;

notify(); 唤醒某个线程

notifyAll(); 唤醒所有线程

2.说一说hashCode()和equals()的关系?

hashCode用于获取哈希码(散列码),equals用于比较两个对象是否相等

如果两个对象相等,那么他们的哈希码一定相同

如果两个对象的哈希码相同,他们不一定相等

3.为什么要重写hashCode()和equals()?

Object类提供的equals()方法默认是用==来进行比较的,也就是说只有两个对象是同一个对象的时候,他门才相等,而现实业务中,我们需要比较的是两个对象的内容如果相同,则认为两个对象相等,所以Object类中的equals()是没有实际用途的,通常重写。

而hashCode()与equals()是联动的,用equals()方法进行比较时,会首先使用hashCode()方法,判断两个对象的哈希码是否相同,如果相同则再进行比较他们的内容,如果两个对象的哈希码都不同,那么这两个对象必不相等。

4.== 和equals()有什么区别?

==运算符作用于基本数据类型时,比较两个数值是否相等,作用于引用数据类型时,比较两个对象的内存地址是否相同,即判断他们是否为同一个对象;

equals()没有重写时,默认用==来比较两个对象的内存地址是否相同,重写后一般按照两个对象的内容进行比较,如内容相同,那么就认为两个对象相等

5.String类有哪些方法?

  • char charAt(int index); 返回指定索引处的字符;
  • String subString(int beginIndex,int endIndex); 从一个字符串中截取一部分子字符串
  • String[] split(String regex);  以指定规则将字符串分割成数组;
  • String trim();  删除字符串前导和后置的空格;
  • int indexOf(String str);  返回子串在此字符串中首次出现的索引;
  • int lastIndexOf(String str);  返回子串在此字符串中最后一次出现的索引;
  • boolean startWith(String prefix); 判断此字符串是否以指定的前缀开头;
  • boolean endWith(String suffix);  判断此字符串是否以指定的后缀结尾;
  • String toUpperCase();  将此字符串所有字符都大写;
  • String toLowerCase();  将此字符串所有字符都小写;
  • String replaceFirst(String regex, String replacement):用指定字符串替换第一个匹配的子串;
  • String replaceAll(String regex, String replacement):用指定字符串替换所有的匹配的子串。

6.String类可以被继承吗?

不可以,String类是被final修饰的,所以不能被继承

在Java中,String类被设计为不可变类,主要表现在它保存字符串的成员变量是final的。

  • Java 9之前字符串采用char[]数组来保存字符,即 private final char[] value;

  • Java 9做了改进,采用byte[]数组来保存字符,即 private final byte[] value;

所以把String类设计为不可变类,主要是出于安全和性能的考虑,可归纳为如下4点。

  • 由于字符串无论在任何 Java 系统中都广泛使用,会用来存储敏感信息,如账号,密码,网络路径,文件处理等场景里,保证字符串 String 类的安全性就尤为重要了,如果字符串是可变的,容易被篡改,那我们就无法保证使用字符串进行操作时,它是安全的,很有可能出现 SQL 注入,访问危险文件等操作。

  • 在多线程中,只有不变的对象和值是线程安全的,可以在多个线程中共享数据。由于 String 天然的不可变,当一个线程”修改“了字符串的值,只会产生一个新的字符串对象,不会对其他线程的访问产生副作用,访问的都是同样的字符串数据,不需要任何同步操作。

  • 字符串作为基础的数据结构,大量地应用在一些集合容器之中,尤其是一些散列集合,在散列集合中,存放元素都要根据对象的 hashCode() 方法来确定元素的位置。由于字符串 hashcode 属性不会变更,保证了唯一性,使得类似 HashMap,HashSet 等容器才能实现相应的缓存功能。由于 String 的不可变,避免重复计算 hashcode,只要使用缓存的 hashcode 即可,这样一来大大提高了在散列集合中使用 String 对象的性能。

  • 当字符串不可变时,字符串常量池才有意义。字符串常量池的出现,可以减少创建相同字面量的字符串,让不同的引用指向池中同一个字符串,为运行时节约很多的堆内存。若字符串可变,字符串常量池失去意义,基于常量池的 String.intern() 方法也失效,每次创建新的字符串将在堆内开辟出新的空间,占据更多的内存。

7.说一说String和StringBuffer有什么区别?

String类是不可变类,一旦一个String对象创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁;

StringBuffer对象则代表一个字符序列可变的字符串,通过StringBuffer提供的append(),insert(),reverse(),setCharAt(),setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换成一个String对象。

8.StringBuffer和StringBuilder有什么区别?

StringBuffer和StringBuilder都表示字符序列可变的字符串对象,他们都有共同的父类AbstractStringBuilder,两个类的构造方法大致相同。但是StringBuffer是线程安全的,StringBuilder是非线程安全的,所以StringBuilder性能略高于StringBuffer,一般情况下,要创建一个内容可变的字符串,优先选择StringBuilder。

9.使用字符串时,new和""推荐使用哪一个?

推荐使用"";

举例:String str = "abc";   和   String str = new String("abc")

当使用第一种,直接使用"abc"字符串直接量时,JVM会使用常量池来管理这个字符串

当使用第二种,JVM会首先使用常量池来管理"abc"这个字符串,然后再调用String类的构造器来创建一个新的String对象,新创建的String对象会被保存到堆内存中。

显然,使用第二种会占用更多的内存,所以推荐使用"";

10.说一说你对字符串拼接的理解?

字符串拼接有很多方式,最常见的有一下四种:

  1. 使用“+”运算符,如果拼接的都是字符串直接量,则使用运算符+直接拼接
  2. StringBuilder,如果拼接的字符串中包含变量,且不要求线程安全,则用StringBuilder,调用append()
  3. StringBuffer,如果拼接的字符串中包含变量,且要求线程安全,则用StringBuffer
  4. String类中的concat方法:如果只是对两个字符串拼接,并且包含变量,则适用concat方法

11.两个字符串相加的底层时如何实现的?

如果拼接的是两个字符串直接量,则在编译时会将其直接优化成一个完整的字符串

如果拼接的字符串包含变量,则编译时编译器采用StringBuilder对其优化,自动创建StringBuilder实例,并调用其append方法,将这些字符串拼接在一起;

12.String str = "abc"; 说一下这个过程会创建什么?放在哪里?

JVM会使用常量池来管理字符串直接量,在执行这句话时,JVM会首先检查常量池中是否有"abc",如没有,则将"abc"放入常量池,如有,则复用常量池中的"abc",将其引用赋值给str。

13.new String("abc"); 是去了哪里?仅仅是堆里吗?

在执行这句话时,JVM会首先使用常量池来管理字符串直接量,然后再创建一个新的String对象,

这个对象会保存在堆内存中,堆中对象的数据会指向常量池中的字符串直接量!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值