《Java核心技术》第一讲

 

5.2、equals、hashcode、toString

package com.macro.mall;

import java.util.Objects;

public class Employer {
    private String name;
    private int age;

    @Override
    public boolean equals(Object otherObject) {
        //检测Object是否为空
        if (otherObject == null) {
            return false;
        }
        //检测this和Object是否指向同一个对象
        if (this == otherObject) {
            return true;
        }
        //比较this和Object是否属于同一个类
        if (getClass() != otherObject.getClass()) {
            return false;
        }
        //将Object转换成相应的类类型变量
        Employer employer = (Employer) otherObject;
        /**
         由于会存在属性值为空的情况,因此如果属性值都为空,Objects.equals则返回true
         如果是数组类型比较的话,那么就使用Arrays.equals进行比较
         */
        return name == employer.name && age == employer.age
                && Objects.equals(name, employer.name) && Objects.equals(age, employer.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    /**
     * 通过使用getClass().getName()方法,防止类名硬编码
     * 此外,如果子类继承该类的话,那么可以就可以通过super.toString进行调用。
     * 如
     *      public String toString() {
     *          return super.toString()
     *          +"[bonus=" + bonus
     *          + "]";
     *          }
     */

    @Override
    public String toString() {
        return getClass().getName() +
                "name=" + nameB
                + ", age=" + age
                + "}";
    }
}

instanceOf可以用来判断是不是指定的一个类或者类的子类或者实现类

如果A类和B类,B类继承了A类,有4种情况:

创建B对象,也就是B b=new B()

1、b instanceOf B   true

2、b instanceOf A true,因为B对象继承了A类

创建A对象,也就是A a = new A()

3、a instance A true

4、a instance B   false,B类继承了A类,也就是说B类有的东西A类不一定存在。

同理,实现类也就如此,

 

5.4 自动装箱与拆箱(编译器执行,而非虚拟机)

基本数据类型:int(4个字节)、short(2个字节)、long(8个字节)、char、byte(1个字节)、float、double、boolean

引用数据类型包括:类(java提供的类或者我们自己定义的类)、接口、数组、枚举、标注

Integer、Short、Long、Char、Byte、Float、Double、Boolean都是java提供的类,因此也是引用类型。

自动装箱:把基本属性类型转换成对应的对象。

自动拆箱:把对象转换成基本属性类型。

如Integer a =10  这个是装箱。首先看=后面的值为10,属于int类型,但是前面是Integer,因此把int类型转成Integer对象。拆箱的话即相反。

5.6 实例化对象

反射机制获取类对象的三种方式:

1、类.getClass    2、Class.forName(String类型的类名)  3、T.class

获取到这些class后,然后调用newInstance方法即可进行实例化。

和new 对象不同的是,new对象的时候Class类被创建了并且已经被实例化了。

而通过类加载机制也就是反射获取的话需要进行实例化也就是调用newInstace方法。

newInstace和new的不同;

newInstace的话只能调用无参构造,而new没有限制,其次newInstace是个方法,而new是一个关键字。

最后通过newInstace的话在工厂模式中可以进行解耦,比如下面代码。

String className = "接口的继承类";
AService o = (AService) Class.forName(className).newInstance();  

如上,className可以用个方法封装获得,那么和每次都要new 对象相比的话代码耦合性就会降低。

但是这个也有个弊端,就是newInstance的效率会比较低。

 

5.7异常

异常包括未检查异常(unchecked运行时异常)和已检查异常(checked)。

未检查异常:空指针异常、数据越界异常等,可以抛出异常。

已检查异常:不能抛出,只能try..catch

 

6.3 lambda表达式

在一个包含lambda表达式的方法中,方法的参数及引用变量都是不可变的,也就是final。

比如一个方法:public void test(int a,int b)    lambda表达式中不能存在类似  a++这种操作或者说有个for循环:for(int i=0;i<count;i++)  然后lambda表达式中引入i,这种会发生变化的变量是不允许存在的,否则会报错。

6.4 内部类

www.cnblogs.com/dearcabbage/p/10609838.html

www.cnblogs.com/wuhenzhidu/p/anonymous.html

 

8.1 泛型

泛型使用类型参数的好处,比如有如下代码

ArrayList list =new ArrayList();
list.add(new File(".....")); 
File file=(File)list.get(0);

 比如上面代码,没有加类型参数的话,ArrayList的话里面可以添加任意类的对象,但是在获取的时候就需要强制转换成不同的类型,此外,在添加并且获取的时候由于没有类型参数编译器不会进行检查,安全性大大降低,而引用了类型参数后就可以解决可读性和安全性。

类型变量的限定

public static <T extends Comparable> T get(String name) {

} 

  注意:这里的话T extends Comparable的话可能会有点奇怪,因为Comparable是个接口,应该是Implements,

官方说明:<T extends BoundingType>,表示T是BoundingType的子类型,T和BoundingType可以是类,也可以是接口,选择extends的原因是更接近子类的概念。

8.5 泛型擦除

Java的泛型是伪泛型,这是因为在编译期间,泛型类型都会被擦除掉,比如下面的代码。

public class Test {

    public static void main(String[] args) {

        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("abc");

        ArrayList<Integer> list2 = new ArrayList<Integer>();
        list2.add(123);

        System.out.println(list1.getClass() == list2.getClass());
    }

}

  定义了2个List,泛型分别是String和Integer类型,但是我们分别获取他们的class,然后进行比较,最后结果会返回true

类型擦除后会变成原始类型,原始类型的通用表达:如果是无限定的类型变量就用Object替换,如果是有限定的类型变量就用这个限定的变量进行替换。

class Pair<T> {  
    private T value;  
    public T getValue() {  
        return value;  
    }  
    public void setValue(T  value) {  
        this.value = value;  
    }  
}

T的话就是无限定的类型变量,那么T就会被替换成Object

class Pair {  
    private Object value;  
    public Object getValue() {  
        return value;  
    }  
    public void setValue(Object  value) {  
        this.value = value;  
    }  
}

 同理,如果最初的泛型为Pair(T extends Comparable),那么T会被替换Comparable。

 

posted @ 2020-09-01 21:52  曾饺  阅读(155)  评论(0编辑  收藏  举报