Java面试基础之String、Integer、Object

本文详细解析了Java中的String、Integer和Object的基础概念,包括它们的数据类型属性、是否可继承、String的不可变性与StringBuilder/StringBuffer的区别、Integer对象的比较、以及Object类的常用方法。重点介绍了内存管理、线程安全和垃圾回收的相关知识点。
摘要由CSDN通过智能技术生成

Java面试基础之String、Integer、Object

String

1、String是Java基本数据类型吗?可以被继承吗?

String不是java的基本数据类型,是引用数据类型,(八大基本数据类型自己内心背一下)

String属于类,引用数据类型为;类。数组,接口。

String不可以被继承!因为String类被final所修饰(自己想一下final的用法)

2、String和StringBuilder、StringBuffer的区别?

推荐阅读https://javabetter.cn/string/builder-buffer.html#stringbuffer%E5%92%8Cstringbuilder%E7%9A%84%E5%8C%BA%E5%88%AB

String、StringBuilder、StringBuffer在Java中都是处理字符串的,他们之间的区别就是String不可以变,StringBuilder和StringBuffer是可以变得。StringBuilder和StringBuffer类似都有append等方法,但是StringBuffer在每个方法上都加上了syschronized关键字,所以StringBuffer是线程安全的。

String:类的对象是不可以改变的,一旦被创立,她所包含的字符内容是不可以改变的。每次对String进行的操作,实际上都会生成一个新的String对象。而不是修改原有对象。这有可能导致性能过载,尤其在大量字符的操作之下。

StringBuilder:其中提供了一系列的方法来进行字符串的增删改查的操作,这些操作是在原有的的字符串对象的底层数组之上进行,不是生成新的String对象。它不是线程安全的(没有外部同步的情况之下,不适用于多线程的环境)。相比较在String,在频繁的进行对字符串进行操作时,StringBuilder可以提供更好的性能。(Java中字符串的“+”操作就是StringBuilder来实现的)

StringBuffer:相比较StringBuilder,他在每个方法前都加了一个synchronized关键字加锁,所以是线程安全的

使用场景的总结:

String:适用于字符串不经常改变的。使用字符串常量少量字符串操作时使用
StringBuilder:适用于单线程环境下需要频繁修改字符串内容的场景,比如:在循环中拼接和修改字符串。
StringBuffer:适用于多线程环境下需要频繁修改字符串内容的场景,保证了字符串的操作的线程安全。

3、String str1 = new String(“abc”)和String str2 = “abc” 的区别?

两个语句都会在字符串的常量池中检查是否已经存在“abc”,如果有就直接引用,,反之,如果没有,就会在常量池中创建“abc”对象,但是不同的是,String str1 = new String(“abc”)还会通过 new String()在堆里创建一个对象(后者可以理解为被前者包含)

String s = new String(“abc”)创建了几个对象?

一个或者两个! 如果字符串池中有abc的话就是一个,反之就是2个。
如果没有abc的话,此时会创建以下两个对象:

①:一个是字符串常量池中的实例:abc
②:另一个是通过new 得到的String的对象的实例,在堆中。

在这里插入图片描述

4、String是不可变类吗?字符串拼接是如何实现的?’

String是不可变得,这意味着一旦一个String对象被创建,其存储得文本内容就不会改变,原因如下:

①:不可变性使得String对象在使用中更加安全,因为字符串通常在java中要进行网络连接,打开文件等操作
②:不可变得对象因为状态不会改变,所以更容易进行缓存和重用,字符串常量池正是基于这个原因。
当代码中出现字符串字面量时,JVM会确保所有得引用都指向常量池中得同一个对象,从而节约内存。
③:因为String的内容不可以变,所以它的哈希值也就会固定不变,这使得String对象特别适合作为HashMap和HashSet等集合的键,因为计算哈希值只需要进行一次,提高哈希表的操作的效率。

因为String是不可变的,所以两个字符串对象相加拼接,会生成一个新的对象。

JDK8之后,对+进行了优化,会基于SringBuilder的append方法进行拼接。

String a = "hello ";
String b = "world!";
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
String ab = sb.toString();

因此,如果笼统地讲,通过加号拼接字符串时会创建多个 String 对象是不准确的。因为加号拼接在编译期还会创建一个 StringBuilder 对象,最终调用 toString() 方法的时候再返回一个新的 String 对象。

5、intern方法有什么作用?

  • 如果当前字符串内容存在于字符串常量池(即 equals()方法为 true,也就是内容一样),直接返回字符串常量池中的字符串

  • 否则,将此 String 对象添加到池中,并返回 String 对象的引用

  • (比较鸡肋,没什么屌用,了解即可)

Integer

1、Integer a= 127,Integer b = 127;Integer c= 128,Integer d = 128;相等吗?

在Jvaa自动装箱的过程中,会使用valueOf()方法来创建Integer对象。

Integer.valueOf()方法会针对数值在-128到127之间的Integer对象使用缓存,因此a和b实际上是引用了常量池中相同的Integer对象。

因为128 超出了Integer缓存的对象(-128到127),因此在自动装箱过程中创建两个不同的Integer对象,他们有不同的的地址值。

所以结果就是:a=b,c != (不等)d

要比较Integer对象的数值是否相等时,应该使用equals方法,而不是==

使用equals方法时,a和b、c和d的比较结构都为true,因为equals()比较的是数值,而不是地址值。

new Integer(10) == new Integer(10) 相等吗

在 Java 中,使用new Integer(10) == new Integer(10)进行比较时,结果是 false。

这是因为 new 关键字会在堆(Heap)上为每个 Integer 对象分配新的内存空间,所以这里创建了两个不同的 Integer 对象,它们有不同的内存地址。

当使用==运算符比较这两个对象时,实际上比较的是它们的内存地址(地址值),而不是它们的值,因此即使两个对象代表相同的数值(10),结果也是 false。

2、String怎么转成Integer的?原理

两种方法:Integer.parseInt(String s) (转成int类型) 和 Integer.valueOf(String s) (转成Integer类型)

一种有参构造函数: public Integer(String s){this.value = parseInt(s, 10) }

不关哪一种,调用的都是Integer类中的parseInt(String s, int radix)方法

Object

1、Object类的常见方法?

万物皆对象
万物指的是Java中所有的类,而这些类都是Object的子类

Object大致提供了11种方法,大致可分为六类:
在这里插入图片描述

对象比较:

①:public native int hashCode(): 用于返回对象的哈希码。
②:public boolean equals(Object obj):用于比较 2 个对象的内存地址是否相等。
③:protected native Object clone() throws CloneNotSupportedException:naitive 方法,返回此对象的一个副本。默认实现只做浅拷贝open in new window,且类必须实现 Cloneable 接口。(Object 本身没有实现 Cloneable 接口,所以在不重写 clone 方法的情况下直接直接调用该方法会发生 CloneNotSupportedException 异常。)
④:toString()方法 返回对象的字符串表示。一般会重写toString方法。 例如Lombok小辣椒 @Data注解会重写toString方法
⑤:lock.wait()方法 ,线程进入等待

⑥、public final native void wait(long timeout) throws InterruptedException:等待 timeout 毫秒,如果在 timeout 毫秒内没有被唤醒,会自动唤醒。

⑦、public final void wait(long timeout, int nanos) throws InterruptedException:更加精确了,等待 timeout 毫秒和 nanos 纳秒,如果在 timeout 毫秒和 nanos 纳秒内没有被唤醒,会自动唤醒。

⑧:lock.notify()随机唤醒一个等待的线程
⑨:nitifyAll() 唤醒所有在等待的线程
⑩:getClass() 反射,获取对象的信息,比如说类名

public static void main(String[] args) {
    User user = new User();
    Class<? extends User> aClass = user.getClass();
    System.out.println(aClass);
}

比如此代码:打印出来aClass为 class com .author.model.User(类)

底层源码:重写了toString

public String toString() {
    return (isInterface() ? "interface " : (isPrimitive() ? "" : "class "))
        + getName();
}

一个简单的三目运算。

11、finalize 当垃圾回收器决定回收对象占用的内存时调用此方法。用于清理资源,但 Java 不推荐使用,因为它不可预测且容易导致问题,Java 9 开始已被弃用。

) ? “” : "class "))
+ getName();
}


一个简单的三目运算。

11、finalize  当垃圾回收器决定回收对象占用的内存时调用此方法。用于清理资源,但 Java 不推荐使用,因为它不可预测且容易导致问题,Java 9 开始已被弃用。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值