java面试张怡3

java基础

    • java基础
      • 29.super.getClass()方法调用
      • 30.String是基本的数据类型吗?
      • 31.String s = “Hello”;s = s + “world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?
      • 32.是否可以继承String类?
      • 33.String s = new String(“xyz”);创建了几个String Object?两者之间有什么区别?
      • 34.String,StringBuffer,StringBuild的区别
      • 37.下面这条语句一共创建了多少个对象:String s = “a”+”b”+”c”+”d”?

29.super.getClass()方法调用

下面程序的输出结果是多少?

import java.util.Date;
public class Test extends Date{
    public static void main(String[] args){
        new Test().test();
    }
}
public void test(){
    System.out.println(super.getClass().getName());
}

1.getClass()方法表示返回运行时类,在object类中这个方法是被final修饰,也就是说不能被子类重写,那么所有的类去调用getClass()方法都其实实在调用从Object类中继承而来的getClass()方法,而这个方法的运行结果是,返回当前运行时类。

2.所以这里super.getClass()的结果是调用了Date类中的getClass()方法,返回值结果是当前运行时类Test,然后通过getName()方法得到类名

那么如何得到父类的类名呢?

1.getClass().getSuperClass().getName();

30.String是基本的数据类型吗?

不是,java中提供了8种基本的数据类型 boolean byte short char int float double long
java.lang.String类是fianl类型的,因此不可以继承这个类,不可以修改这个类,为了提高效率节省空间,我们应该使用StringBuffer类

31.String s = “Hello”;s = s + “world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?

原始的String对象的内容没有改变

String创建字符串对象的过程是典型的栈内存与堆内存的对应关系,但是String类尤其特殊的地方——构造方法实例化的两次开辟空间与直接赋值实例化的自动入字符串常量池

public class TestString {
    public static void main(String[] args) {
        String str1 = "Lance";
        String str2 = new String("Lance");
        String str3 = str2; //引用传递,str3直接指向st2的堆内存地址
        String str4 = "Lance";
        /**
         *  ==:
         * 基本数据类型:比较的是基本数据类型的值是否相同
         * 引用数据类型:比较的是引用数据类型的地址值是否相同
         * 所以在这里的话:String类对象==比较,比较的是地址,而不是内容
         */
         System.out.println(str1==str2);//false
         System.out.println(str1==str3);//false
         System.out.println(str3==str2);//true
         System.out.println(str1==str4);//true
    }

}

分析

1.对于普通的通过构造方法创建实例化对象的方式,我们很熟悉栈内存对象名和堆内存中对象的对应关系
java面试张怡3_第1张图片

2.这样的对应关系其实不能反应String类的特殊之处,String str = new String(“hello”);

1.首先会在堆内存中产生一个匿名对象
java面试张怡3_第2张图片
2.然后new关键字会在堆内存中再次开辟一个位置指向str,原来的匿名对象变为垃圾
java面试张怡3_第3张图片

3.对于直接赋值的方式创建实例化对象

32.是否可以继承String类?

不可以,String类是final类不可以被继承

33.String s = new String(“xyz”);创建了几个String Object?两者之间有什么区别?

一个或者两个
这个题非常经典,其实在31中已经分析过了,如果之前字符串常量池中没有”xyz”,那么这里”xyz”会创建一个匿名对象,然后new又会创建一个xyz对象,原来的匿名对象变为垃圾,这样创建了两个对象。如果字符串常量池中有”xyz”,那么”xyz”会直接从字符串常量池中取,这样创建了一个对象。

这里介绍一下构造方法实例化对象的手工入池,我们知道通过构造方法实例化对象的产生的两个对象是不像直接赋值实例化对象那样会自动进入字符串常量池的,但是我们可以通过手工入池的方式进入

public class TestString {
    public static void main(String args[]){
     String str =new String("Lance").intern();//对匿名对象"hello"进行手工入池操作
     String str1="Lance";
     System.out.println(str==str1);//true
    }
}

34.String,StringBuffer,StringBuild的区别

1.这三个类的实例化对象都是字符串变量
2.在运行速度上StringBulid > StringBuffer > String
StringBulid和StringBuffer是可变类可以通过append方法来改变字符串对象的内容,而String类是不可变的,需要不停的创建对象,所以速度最慢。StringBuild是线程不可靠的,StringBuffer是线程可靠的,线程不可靠的速度更快一些
3.需要注意的是String str = “hello” + “world”;
这里并没有创建两个匿名对象hello和world,而是一个helloworld,原因在于java在给str直接赋值的的时候,编译器会先作拼接操作,然后再创建对象,和
String str1 = hello;
String str2= world;
String str = str1 + str2;
是完全不同的方式

37.下面这条语句一共创建了多少个对象:String s = “a”+”b”+”c”+”d”?

这里只是创造了一个String对象
String类型的相加

1.String s = “a”+”b”+”c”+”d”,编译器在编译阶段直接编译成abcd,显然abcd会进入字符串常量池
2.String s1 = a;String s2 =b;String s = s1+s2;
或String s1 = a;String s2= s1 +”b”;
String类型的相加实际上是先创建一个StringBuffer对象,然后通过append方法来完成字符串拼接,然后再将StringBuffer类型转为String类型,这个新对象储存在堆中。
3.代码测试结果

String s1 = "a";
String s2 = S1 + "b";
String s2 = "a" + "b";
syso(s2 == "ab");//false
syso(s3 == "ab");//true

你可能感兴趣的:(Java面试)