Java中使用泛型和Objects类需要注意的几个地方

Java中使用泛型和Objects类需要注意的几个地方

一、泛型

泛型,即“参数化类型”,将类型由原来的具体的类型参数化,可以让Java类、调用方法动态地改变类型。

1.泛型类型必须是引用类型

泛型本质是Object类,而int不是,Java中的泛型是通过编译时的类型擦除(去泛型化)来完成的,当泛型被类型擦除后都变成Object类型。但是Object类型不能指代像int,double这样的基本类型只能指代Integer,Double这样的引用类型。

所以使用泛型时不小心使用了int等基本数据类型会报错

public class Demo01 {

    public static void main(String[] args) {
        Person<int> p = new Person<>();
        //int处报错:Syntax error, insert "Dimensions" to complete ReferenceType
        //需要插入一个(类型)方向来完善引用类型
        //将int改成相对应的包装类或Object类
        p.setData(100);
        System.out.println(p.getData());
        System.out.println(p.toString());
    }

}
class Person<T>{    
    private T data;
    public T getData() {
        return data;
        }
    public void setData(T data) {
    this.data = data; 
    }
    public String toString() {
        return "ClassName [data=" + data + "]";
    }
    
}
2.通配符需要注意的地方

泛型使用?作为类型通配符,表示未知类型,可以匹配任何类型,当使用通配符时,带有通配符的对象,对泛型类中的参数为泛型的方法起到了限制,不能再使用。?代表的类型参数是未知,所以无法添加元素,也就是无法使用set方法,但是由于Object是所有类的父类,所以可以将元素定义为Object类并取出来,可以使用get方法。
但是如果就是想使用通配符的情况下还想使用set方法,可以使用
Plate<? super Apple> p = new Plate<Apple>(a1);
即当下界为调用的类型的时候可以使用set方法,但是当上界为调用的类型时不能使用set方法。
Plate<? extends Apple> p = new Plate<Apple>(a1);

package until4_1topHalf;

public class Demo1 {

    public static void main(String[] args) {
        Apple a1 = new Apple(111);
        Plate<? extends Fruit> p = new Plate<Apple>(a1);
        //p.setData(a1);这条语句会报错
        //The method setData(capture#1-of ?) in the type Person<capture#1-of ?> is not applicable for the arguments (int)
        //类型Person中的方法setData(capture#1-of ?)不适用于参数(int)
        System.out.println(p.getData());
        System.out.println(p.toString());
    }

}
interface Fruit{}
class Apple implements Fruit{
    Object size;
    public Apple(int size) {
        super();
        this.size = size;
    }
    public String toString() {
        return "Apple [size=" + size + "]";
    }
    
}
class Plate<T>{
    T data;
    public Plate(T data) {
        super();
        this.data = data;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
    public String toString() {
        return "Plate [data=" + data + "]";
    }
}
/*输出为:
 *Apple [size=111]
 *Plate [data=Apple [size=111]]
 */

二、Objects

1.Object与Objects区别

Object是所有类的基类,位于java.lang包中,使用时不需要导入包

Objects的所有方法是static修饰的,可以通过类名直接访问;而Objects类本身又final修饰,不能被继承,说明是一个工具类,Objects位于java.until包中,使用时一定要导包才能使用。

2.Objects使用注意

Objects不能被构造 创建对象时报错:The constructor Objects() is not visible

调用Objects的方法参数基本上不能传入基本数据类型,除了三个判断范围的方法除外:

1.checkFromIndexSize(int fromIndex, int size, int length)

2.checkFromToIndex(int fromIndex, int toIndex, int length)

3.checkIndex(int index, int length)

这三个方法的参数都是int类型,同时可以将一个int类型强制转为Object类或Integer类也是能使用的,同时需要注意的是调用这三个方法返回结果为false时是直接返回异常的,同样结果为false时返回异常的方法有:

1.public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier):检查指定的对象引用是否为null ,true返回NullPointerException 类异常。

2.public static <T> T requireNonNull(T obj, String message) :检查指定的对象引用是否为null ,true返回NullPointerException 类异常。

import java.util.Objects;

public class Demo02 {

    public static void main(String[] args) {
        //Objects o = new Objects();
        //报错:The constructor Objects() is not visible
        Person p1 = new Person();
        Person p2 = null;
        int i1 = 80;
        int i2 = 99;
        Object i3 = (Object)i2;
        Integer i4 = (Integer)i2;
        System.out.println(Objects.checkIndex(8, 100));
        System.out.println(p1.equals(p2));
        //System.out.println(i2.equals(i1));
        //参数为基本类型报错:Cannot invoke equals(int) on the primitive type int
        
        /*判断子范围从fromIndex (第一个参数,范围包括)到fromIndex + size (参数二、不包括)
         * 是范围界限内0 (包括)到length (参数三、不包括)。 
         * true返回参数1的值,false返回IndexOutOfBoundsException类异常
         */
        System.out.println(Objects.checkFromIndexSize(5, 2, i2));
        /*检查是否在子范围从参数一(包括)到参数二(不包括)
         * 是范围界限内0 (包括)到length (参数三,不包括)
         * 不包括同样返回异常
         */
        System.out.println(Objects.checkFromToIndex(10, 99, i4));
        /*检查index是否在0 (含)到length (不包括)范围内。
         *不包括同样返回异常
         */
        System.out.println(Objects.checkIndex(8, 100));
        
        System.out.println(Objects.equals(p2,p1));
        System.out.println(Objects.isNull(p2));
        System.out.println(Objects.requireNonNull(p1));
    }

}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容