【Java 问题】基础——常用类

接上文

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

String是Java基本数据类型吗?

不是。Java 中的基本数据类型只有8个:byte、short、int、long、ϐ loat、double、char、boolean;除了基本类型(primitive type),剩下的都是引用类型(referencetype)。

String是一个比较特殊的引用数据类型。

String 类可以继承吗?

不行。String 类使用 final 修饰,是所谓的不可变类,无法被继承。

32.String和StringBuilder、StringBuffer的区别?

  • String:String 的值被创建后不能修改,任何对 String 的修改都会引发新的 String对象的生成。
  • StringBuffer:跟 String 类似,但是值可以被修改,使用 synchronized 来保证线程安全。
  • StringBuilder:StringBuffer 的非线程安全版本,性能上更高一些。

33.String str1 = new String(“abc”)和String str2 = “abc” 和 区别?

两个语句都会去字符串常量池中检查是否已经存在 “abc”,如果有则直接使用,如果没有则会在常量池中创建 “abc” 对象。

在这里插入图片描述
但是不同的是,String str1 = new String(“abc”) 还会通过 new String() 在堆里创建一个 “abc” 字符串对象实例。所以后者可以理解为被前者包含。

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

很明显,一个或两个。如果字符串常量池已经有“abc”,则是一个;否则,两个。

当字符创常量池没有 “abc”,此时会创建如下两个对象:

  • 一个是字符串字面量 “abc” 所对应的、字符串常量池中的实例
  • 另一个是通过 new String() 创建并初始化的,内容与"abc"相同的实例,在堆中。

34.String不是不可变类吗?字符串拼接是如何实现的?

String的确是不可变的,“+”的拼接操作,其实是会生成新的对象。

在这里插入图片描述
在jdk1.8之前,a和b初始化时位于字符串常量池,ab拼接后的对象位于堆中。经过拼接新生成了String对象。如果拼接多次,那么会生成多个中间对象。

在这里插入图片描述
在Java8时JDK对“+”号拼接进行了优化,上面所写的拼接方式会被优化为基于StringBuilder的append方法进行处理。Java会在编译期对“+”号进行处理。下面是通过javap -verbose命令反编译字节码的结果,很显然可以看到StringBuilder的创建和append方法的调用。

在这里插入图片描述
也就是说其实上面的代码其实相当于:

在这里插入图片描述
此时,如果再笼统的回答:通过加号拼接字符串会创建多个String对象,因此性能比StringBuilder差,就是错误的了。因为本质上加号拼接的效果最终经过编译器处理之后和StringBuilder是一致的。

当然,循环里拼接还是建议用StringBuilder,为什么,因为循环一次就会创建一个新的StringBuilder对象.

36.Integer a= 127,Integer b = 127;Integer c= 128,Integer d = 128;相等吗?

答案是a和b相等,c和d不相等.

  • 对于基本数据类型==比较的值
  • 对于引用数据类型==比较的是地址

Integer a= 127这种赋值,是用到了Integer自动装箱的机制。自动装箱的时候会去缓存池里取Integer对象,没有取到才会创建新的对象。

如果整型字面量的值在-128到127之间,那么自动装箱时不会new新的Integer对象,而是直接引用缓存池中的Integer对象,超过范围 a1==b1的结果是false

在这里插入图片描述

什么是Integer缓存?

因为根据实践发现大部分的数据操作都集中在值比较小的范围,因此 Integer 搞了个缓存池,默认范围是 -128 到 127,可以根据通过设置 JVM-XX:AutoBoxCacheMax= 来 修改缓存的最大值,最小值改不了。

实现的原理是int 在自动装箱的时候会调用Integer.valueOf,进而用到了IntegerCache。

在这里插入图片描述
很简单,就是判断下值是否在缓存范围之内,如果是的话去 IntegerCache 中取,不是的话就创建一个新的Integer对象

IntegerCache是一个静态内部类, 在静态块中会初始化好缓存值。

在这里插入图片描述

37.String怎么转成Integer的?原理?

String转成Integer,主要有两个方法:

  • Integer.parseInt(String s)
  • Integer.valueOf(String s)

不管哪一种,最终还是会调用Integer类内中的 parseInt(String s, int radix) 方法。

38.Object 类的常见方法?

Object 类是一个特殊的类,是所有类的父类,也就是说所有类都可以调用它的方法。它主要提供了以下 11 个方法,大概可以分为六类:

在这里插入图片描述
对象比较:

  • public native int hashCode() :native方法,用于返回对象的哈希码,主要使用在哈希表中,比如JDK中的HashMap。
  • public boolean equals(Object obj):用于比较2个对象的内存地址是否相等,String类对该方法进行了重写用户比较字符串的值是否相等。

对象拷贝:

  • protected native Object clone() throws CloneNotSupportedException:naitive方法,用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。

对象转字符串:

  • public String toString():返回类的名字@实例的哈希码的16进制的字符串。建议Object所有的子类都重写这个方法。

多线程调度:

  • public final native void notify():native方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
  • public final native void notifyAll():native方法,并且不能重写。跟notify一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。
  • public final native void wait(long timeout) throws InterruptedException:native方法,并且不能重写。暂停线程的执行。注意:sleep方法没有释放锁,而wait方法释放了锁 。timeout是等待时间。
  • public final void wait(long timeout, int nanos) throws InterruptedException:多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。所以超时的时间还需要加上nanos毫秒。
  • public final void wait() throws InterruptedException:跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念

反射:

  • public final native Class<?> getClass():native方法,用于返回当前运行时对象的Class对象,使用了final关键字修饰,故不允许子类重写。

垃圾回收:

  • protected void finalize() throws Throwable :通知垃圾收集器回收对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰深入学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值