目录

 01-equals方法 

理解解析 :

 02-线程效率与安全

理解解析:

03-toString的默认实现

理解解析:

04-list的remove与removeAll

理解解析:

05-装箱、拆箱

理解解析:

06-Integer与int

理解解析:

07-泛型

01

理解解析:

02

理解解析:

03

理解解析:

08-Comparable与Comparator

理解解析:

09-hashCode

理解解析:

10-static代码块与代码块

 理解解析:


equals方法 

java选择提易错题分享 java挑错题_开发语言

错选为:

java选择提易错题分享 java挑错题_java选择提易错题分享_02

 正确结果为:

java选择提易错题分享 java挑错题_字符串_03

理解解析 :

1、== 用于比较两个对象,且比较的是两个对象内存中的地址。

stu1为字符串“Tom”,stu2是再次new出来的字符串,明显地址值不同,一定会先输出false。

2、equals属于Object类,默认情况下的实现如下图,就是 ==

java选择提易错题分享 java挑错题_开发语言_04

 因而此处方法重写了 。

3、Student stu = (Student) obj  这里用到了向下造型 如图

java选择提易错题分享 java挑错题_开发语言_05

对于子类拥有父类没有的变量与方法,则需要将父类强制类型转换为子类类型,则可以引用子类中的变量和方法,题中obj可以引用Student类中的变量name。

4、接下来便是stu.name 与 this.name判断是否相等 ,而两者都是字符串String,因而需比较的是字符串字面量 ,因而需要用equals方法而不是==,字符串的比较不能用==比较,因为比较的不是地址。

 02-线程效率与安全

java选择提易错题分享 java挑错题_java选择提易错题分享_06

 

java选择提易错题分享 java挑错题_开发语言_07

正确选择为:B

理解解析:

1、StringBuilder:效率高

       StringBuffer:线程安全    而题中应有StringBuffer因而安全

2、替换后只是效率提高,结果没有影响

3、已知String字符串本身是不变的,因而 return "<" + this.name + ">" 字符串的拼接会使每一次拼接都new出一个新的字符串,并没有提高程序性能。

03-toString的默认实现

java选择提易错题分享 java挑错题_泛型_08

当时不明所以,正确答案为:A、C 

理解解析:

1、toString方法属于Object类,源码中默认形式如下:

java选择提易错题分享 java挑错题_java选择提易错题分享_09

其省略了this ,具体为: 

return this.getClass().getName() + "@" + Integer.toHexString(hashCode());

2、getClass():获得字节码类型      getName() : 类的全限定类名(带包结构),对于Integer.toHexString(hashCode())指的就是调用hashCode方法。

3、js是对象,题中最后两行本质一样,输出对象就是会默认调用对象的toString 方法

04-list的remove与removeAll

java选择提易错题分享 java挑错题_泛型_10

java选择提易错题分享 java挑错题_字符串_11

正确选择为:A 

理解解析:

1、c选项只可删除一个java ,而对于removeAll的使用如下图,括号内需得是集合

java选择提易错题分享 java挑错题_java_12

 2、对于B选项,for循环中i由0至list的长度,但对于每一次的remove,list的长度会随之减少,会致使遍历不全,A选项中由末尾至开头则list长度的减少不会有影响。

05-装箱、拆箱

java选择提易错题分享 java挑错题_开发语言_13

 正确选择为:false  true

理解解析:

public class Demo23 {
    public Integer startingI;
    public void methodA() {
        startingI = new Integer(25);//源码中的i就等于startingI,两者地址指向一样
        methodB(startingI); // 跳到methodB()
    }
    // i2 = startingI 传递地址
    private void methodB(Integer i2) {
        i2 = i2.intValue();//这一句包含了自动拆箱后装箱
        // i2.intValue(); 拆箱 25
        /* i2 = 25 ; 装箱   Integer.valueOf(25) 返回一个Integer指定的int值的Integer实例             
        *  i2 指向常量池  常量池缓存-128到127(含)范围内的值
        */
        //而startingI一直指向new出来的Integer   两者地址指向不同

        System.out.println(i2 == startingI); // false
        // Integer类中的toString方法已经重写过了, 只比较内容
        System.out.println(i2.equals(startingI)); // true
    }

    public static void main(String[] args) {
        new Demo23().methodA(); // 跳到 methodA()
    }

}

知识点细化拓展:

自动装箱,分情况:

1、装箱的值在常量池范围内 -128~127 则会装到常量池

2、装箱的值超出常量池范围,就等同于new了一个新对象

public class Demo23_2 {
    public static void main(String[] args) {
        Integer i1 = 25;
        Integer i2 = 25;
        System.out.println(i1 == i2);//均指向常量池 地址内容均一致

        i1 = 225; // new Integer(225)
        i2 = 225; // new Integer(225)
        // 超过了常量池的范围 -128~127
        System.out.println(i1 == i2);//地址不同
    }
}

06-Integer与int

java选择提易错题分享 java挑错题_开发语言_14

 

java选择提易错题分享 java挑错题_java选择提易错题分享_15

 

java选择提易错题分享 java挑错题_字符串_16

 正确选择为:D

理解解析:

1、对于A、B选项,i的值都改变了,结果一定改变;

2、C选项中将addOne方法改为私有的,则该方法只能在同一类中被访问,Client类中无法访问;

3、对于  Integer 基本数据类型  和  int  包装类型  在使用上是无缝衔接的;但是在定义类的成员变量时,类型还是建议使用包装类型。 

07-泛型

Arrays:是数组对应的工具类

Collections:是集合对应的工具类

import java.util.Arrays;
import java.util.List;

public class Demo29 {
    public static void main(String[] args) {
        int[] arr = {1,2,3,4};
        List list = Arrays.asList(arr);

        Integer[] arrInt = {1,2,3,4};
        List<Integer> list1 = Arrays.asList(arrInt);

        // 不指定类型的集合, 就只能转换成Object类型的数组
        Object[] arr1 = list.toArray();

        // 有泛型的集合, 可以通过传递指定的数组类型来转换
        Integer[] arr2 = list1.toArray(new Integer[0]);

    }
}

01

java选择提易错题分享 java挑错题_字符串_17

java选择提易错题分享 java挑错题_字符串_18

java选择提易错题分享 java挑错题_java_19

正确选择:C

泛型知识点: 泛型 —> <具体类型>  将类型作为参数,也可以是Object,用于规范程序员,以防程序员乱写导致运行失败,因而在编译期就约束好类型。

理解解析:

1、List<String> strings = new ArrayList<>() : 约束程序员只能向strings中添加String类型的对象。

2、题中若没有泛型,strings本质上是一个可以存放所有对象的集合;但是因为添加了泛型,因而编译时指定了类型。

3、A中strings虽然没有内容,但是不影响编译,且若有内容get出来的也是String类型,是正确的,Iterator可泛型可不泛型;

4、若strings没有指定类型,则可以用toArray方法转换为Object类型的数组

02

 

java选择提易错题分享 java挑错题_字符串_20

 正确选择:A、C

理解解析:

  1. 根据泛型,对象类型必须是可比较的,且返回值也得是同一类型,A中123为int类型,“456”字符串类型,都为Object类型,且可比较;同理,123不为String类型,因而B选项不对。
  2. C选项中,虽然123为int类型,456为Integer类型,但是在使用上是无缝衔接的是一样的,而后对其结果为Integer类型进行拆箱赋值给了i,拆箱后类型为int;D显然不对

03

java选择提易错题分享 java挑错题_java选择提易错题分享_21

 运行结果为:0042

理解解析:

  1. 首先,确定程序无编译错误,再者 泛型 只在当前类中有效。
  2. 虽然集合intlist的泛型类型为Integer,但是进入到append方法时,方法内参数没有带泛型,因而在这个方法内list集合内可以存放任何类型的数据,因而字符串“0042”可以添加成功;若该方法有相同泛型,则添加不成功。

08-Comparable与Comparator

知识点:

1. Comparable<T>: (我)可比较的     compareTo(Object / T   obj)  有泛型则用泛型
2. Comparator<T>: 比较器, 作用:比较两个对象   compare(Object / T  obj1, Object / T  obj2)

java选择提易错题分享 java挑错题_字符串_22

 

java选择提易错题分享 java挑错题_java选择提易错题分享_23

 正确选择:C

理解解析:

题中TreeMap类的tm对象的键会根据给定的比较器进行排序,且题中键的比较为由大到小。

09-hashCode

java选择提易错题分享 java挑错题_字符串_24

java选择提易错题分享 java挑错题_泛型_25

 正确选择:D

理解解析:

由于HashSet与HashMap都是散列的,没有顺序,且是不允许重复的,因而第一次输出set的大小应是2,排除A、B;令k2.i=1,则是对k2的value值进行更改,set大小不变;set.remove(k1)后,set的大小减一后为1;而因为k2的值目前是1,因而进行set.remove(k2)时,实际上是根据1值去计算hashCode值进行寻找位置的,找的仍然是之前的k1的地址,因而会发现1那个值已经被删了、不存在了,而k2本身仍存在不变,set的大小仍为1。要想把k2删除,只有将k2的值改为2后remove(k2)才行。

10-static代码块与代码块

理解:

public class Demo4 {
    public static void main(String[] args) {
        final int i;
        // 所有的局部变量/临时变量 在使用前都必须初始化
        i = 10;
        System.out.println(i);
    }
}
class Foo {
    final int age = 10;// new之后,构造器之前执行
    final Foo foo;
    //代码块(创建对象之后,构造器之前执行) 在每次调用构造器之前都会执行一次代码块
    {
        foo = new Foo();
    }
    //无参构造器
    public Foo() { }
    //有参构造器
    public Foo(int age) { }
}

创建对象的步骤:

        第一次创建对象:

  1. 类加载(在第二次开始创建对象时,就不需要加载了) 
  2. new -> 分配内存空间
  3. 给直接初始化的变量赋值
  4. 调用代码块
  5. 选择一个构造器使用                                        

类加载的执行顺序:(对于前两者,没有先后顺序 ,谁先写就先执行谁)

  • 静态代码块     static{ }
  • 静态的成员变量    如 static  int  age  =  1
  • 静态的成员方法    -> 会先加载到内存中,都是不执行

类加载什么时候会加载:

  • 第一次使用类的时候
  • 第一次被创建对象
  • 调用静态方法
  • 调用子类的静态方法
  • 第一次创建子类对象
  • 调用静态成员变量
  • 调用子类的静态成员变量
  • 主动加载   Class.forName("类的名字  java.lang.String")

例题:重要

java选择提易错题分享 java挑错题_字符串_26

 结果为:

java选择提易错题分享 java挑错题_泛型_27

 理解解析:

首先,在类B中有主方法,而主方法是静态方法,调用静态方法前会先进行类加载,而B又是A的子类,因而会先加载类A中的静态代码块,然后再加载B中的静态代码块;接着执行主方法new B对象,由于B继承A ,因而会先new A,则会调用A的构造器,而每一次调用构造器之前都会先执行一次代码块,A new完后new B,同理,接着执行B的代码块而后调用B的构造器。