JavaSE-易错题集-003

1. 

1

2

3

4

5

6

7

8

9

10

public class CharToString {

 public static void main(String[] args)

 {

  char myChar = 'g';

  String myStr = Character.toString(myChar);

  System.out.println("String is: "+myStr);

  myStr = String.valueOf(myChar);

  System.out.println("String is: "+myStr);

 }

}

此代码片段输出正确的值是()

  • A String is: g
      String is: g
  • B String is: 103
      String is: g
  • C String is: g
      String is: 103
  • D String is: 103
      String is: 103

正确答案:A

考点:String 中toString()、valueOf()方法的返回值类型

 题解:

public static String toString(char c) { return String.valueOf(c); }
 public static String valueOf(char c) { char data[] = {c};  return new String(data, true); }

返回的都是字符串,只有char变成 int 的时候才会变为对应的assic码


2. 下列程序执行后输出结果为(      )

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

class BaseClass {

    public BaseClass() {}

    {

        System.out.println("I’m BaseClass class");

    }

     static {

         System.out.println("static BaseClass");

     }

 }

 public class Base extends BaseClass {

     public Base() {}

     {

         System.out.println("I’m Base class");

     }

     static {

         System.out.println("static Base");

     }

     public static void main(String[] args) {

         new Base();

     }

 }

  • A static BaseClass
      I’m BaseClass class
      static Base
      I’m Base class
  • B I’m BaseClass class
      I’m Base class
      static BaseClass
      static Base
  • C I’m BaseClass class
      static BaseClass
      I’m Base class
      static Base
  • D static BaseClass
      static Base
      I’m BaseClass class
      I’m Base class

正确答案:D

考点:静态代码块、代码块、构造函数在父类子类中的运行顺序~

题解:

执行顺序从左到右:

    父类静态代码块 ->子类静态代码块 ->父类非静态代码块 -> 父类构造函数 -> 子类非静态代码块 -> 子类构造函数。

案例代码如下:

public class Father {  static {
        System.out.println("父类静态代码块");    }

    {
        System.out.println("父类非静态代码块");    }  public Father(){
        System.out.println("父类构造函数");    }   }
public class Son extends Father{  static {
        System.out.println("子类静态代码块");    }

    {
        System.out.println("子类非静态代码块");    }  public Son(){
        System.out.println("子类构造函数");    }  public static void main(String[] args) {
        Son son = new Son();    }
}

/*
结果为:   父类静态代码块
          子类静态代码块
          父类非静态代码块
          父类构造函数
          子类非静态代码块
          子类构造函数 
*/

3. 以下程序执行的结果是:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

class X{

    Y y=new Y();

    public X(){

        System.out.print("X");

    }

}

class Y{

    public Y(){

        System.out.print("Y");

    }

}

public class Z extends X{

    Y y=new Y();

    public Z(){

        System.out.print("Z");

    }

    public static void main(String[] args) {

        new Z();

    }

}

  • A ZYXX
  • B ZYXY
  • C YXYZ
  • D XYZX

正确答案:C

考点:初始化过程

题解:

初始化过程:

1 初始化父类的静态成员变量和静态代码块

2 初始化子类中的静态成员变量和静态代码块

3 初始化父类的普通成员变量和非静态代码块,再执行父类的构造方法

4 初始化子类的普通成员变量和代码块,再执行子类的构造方法

本题顺序:

(1) 初始化父类的普通成员变量和代码块,执行 Y y  = new Y(); 输出Y

(2) 再执行父类的构造方法 输出X

(3) 初始化子类的普通成员变量和代码块,执行Y   = new Y(); 输出Y

(4) 再执行子类的构造方法 输出Z

所以最后输出YXYZ


4. 有以下代码片段:

1

2

3

4

5

String str1="hello";

String str2="he"new String("llo");

System.out.println(str1==str2);

请问输出的结果是:

  • A true
  • B 都不对
  • C null
  • D false

 

正确答案:D

考点:字符串,常量池

题解:

    1)String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法。在Java中,被final修饰的类是不允许被继承的,并且该类中的成员方法都默认为final方法。

    2)String类底层是char数组来保存字符串的。

    对String对象的任何改变都不影响到原对象,相关的任何change操作都会生成新的对象 


    字符串常量池 


    在class文件中有一部分来存储编译期间生成的字面常量以及符号引用,这部分叫做class文件常量池,在运行期间对应着方法区的运行时常量池。

    JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池

    工作原理 

    当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。

    实现前提 

    字符串常量池实现的前提条件就是Java中String对象是不可变的,这样可以安全保证多个变量共享同一个对象。如果Java中的String对象可变的话,一个引用操作改变了对象的值,那么其他的变量也会受到影响,显然这样是不合理的。

    String str1 = "hello"; 

    这里的str1指的是方法区中的字符串常量池中的“hello”,编译时期就知道的;

    String str2 = "he" + new String("llo"); 

    这里的str2必须在运行时才知道str2是什么,所以它是指向的是堆里定义的字符串“hello”,所以这两个引用是不一样的。

    如果用str1.equal(str2),那么返回的是true;因为String类重写了equals()方法。

    编译器没那么智能,它不知道"he" + new String("llo")的内容是什么,所以才不敢贸然把"hello"这个对象的引用赋给str2.

    如果语句改为:"he"+"llo"这样就是true了。

    new String("zz")实际上创建了2个String对象,就是使用“zz”通过双引号创建的(在字符串常量池),另一个是通过new创建的(在堆里)。只不过他们的创建的时期不同,一个是编译期,一个是运行期。

    String s = "a"+"b"+"c"; 

    语句中,“a”,"b", "c"都是常量,编译时就直接存储他们的字面值,而不是他们的引用,在编译时就直接将它们连接的结果提取出来变成"abc"了。


5. 下面有关 java 类加载器,说法正确的是?()

  • A 引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用C++来实现的
  • B 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。
  • C 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类
  • D tomcat 为每个 App 创建一个 Loader,里面保存着此 WebApp 的 ClassLoader。需要加载 WebApp 下的类时,就取出 ClassLoader 来使用

正确答案:B C D

考点:java的类加载器

题解:

类的加载是由类加载器完成的,类加载器包括:根加载器(BootStrap)、扩展加载器(Extension)、系统加载器(System)和用户自定义类加载器(java.lang.ClassLoader 的子类)。从Java2(JDK1.2)开始,类加载过程采取了父亲委托机制(PDM)。PDM更好的保证了Java平台的安全性,在该机制中,JVM自带的BootStrap 是根加载器,其他的加载器都有且仅有一个父类加载器。类的加载首先请求父类加载器加载,父类加载器无能为力时才由其子类加载器自行加载。JVM不会像Java程序提供对Bootstrap的引用。下面是关于几个类加载器的说明:

        Bootstrap:一般用本地代码实现,负责加载JVM基础核心类库(rt.jar);

        Extension:从java.ext.dirs 系统属性所指定的目录中加载类库,它的父加载器时Bootstap;

        system class loader:又叫应用类加载器,其父类是Extension。它是应用最广泛的类加载器。它从环境变量classpath 或者系统属性 java.class.path 所指定的目录中加载类,是用户自定义加载器的默认父加载器。

        用户自定义类加载器:java.lang.ClassLoader 的子类

        父类委托机制是可以修改的,有些服务器就是自定义类加载器优先的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值