有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java为什么需要泛型类型然后是类型reasure,尽管我们可以使用对象Pojo

我有这样的代码:

public class Crate<T> {
    private T contents;

    public T emptyCrate() {
        return contents;
    }

    public void packCrate(T contents)
    {
        this.contents = contents;
    }
}

现在我们知道了-最终它将“转换”为以下代码:

public class Crate {
    private Object contents;

    public Object emptyCrate() {
        return contents;
    }

    public void packCrate(Object contents) 
    {
        this.contents = contents;
    }
}

那么,如果我已经可以创建一个类似于Object的类,那么为什么我们需要创建泛型呢


共 (5) 个答案

  1. # 1 楼答案

    它会变成什么并不重要

    相反,汇编阶段很重要。泛型保证编译类型的类型安全(修复编译时错误比修复运行时错误容易得多)

    它还消除了强制转换,并能够实现通用算法

  2. # 2 楼答案

    当人们谈论类型擦除时,他们通常关注泛型类本身。但是泛型还有另一个重要的地方:调用站点

    例如,如果您有以下代码:

    Crate<Integer> intCrate = new Crate<>();
    intCrate.packCrate(0);
    Integer contents = intCrate.emptyCrate();
    

    然后,当它被编译时,它实际上变成:

    Crate intCrate = new Crate();
    intCrate.packCrate(0);
    Integer contents = (Integer) intCrate.emptyCrate();
                     // ^ Important! This cast.
    

    即,有自动插入的类型转换。此外,隐式地,还检查了packCrate的参数是否与Integer兼容,因此您无法写入:

    intCrate.packCrate("hello");
    

    现在,您可以在不使用泛型的情况下执行此操作,您可以自己放入这些强制转换,但编译器无法帮助您了解Crate中放入了什么。你可以这样写:

    Crate crate = new Crate();
    crate.packCrate(0);
    String contents = (String) crate.emptyCrate();
    

    这将在运行时失败,因为板条箱包含Integer,而不是String

    泛型只是帮助您不必记住允许传递给实例的内容,以及从中获得的内容

  3. # 3 楼答案

    泛型中的模板参数用于编译时安全。如果您编写以下代码,编译器将阻塞,例如:

    Crate<Integer> cr;
    Object o;
    
    cr.packCrate(o);  // compilation error here
    

    它还可以声明用作参数的任何类都将实现某些方法:

    Interface I {
        void myMethod();
    }
    
    class Crate<T extends I> {
        private T contents;
        ...
        public void applyMethod() {
            contents.myMethod();      // T shall implement myMethod
        }
    }
    

    事实上,一切都可以通过显式强制转换来完成,但是您将只得到运行时错误,而泛型允许编译时检测错误

  4. # 4 楼答案

    Java中的所有集合都是泛型。这是使用泛型的最好例子。例如,创建类列表。它将容纳哪些类型的对象?当您创建List类时,您不知道它将包含哪些类型,所以您使用泛型。当您使用List类时,您会说,您希望放置Integersnew List<Integer

  5. # 5 楼答案

    你看,java代码被翻译成字节码。那么,为什么不用字节码编写程序呢?他们被翻译了吗?或者,准确地说:JIT编译器会在某个时刻将大部分字节码转换为机器码。那你为什么坚持写java源代码,而不是二进制机器代码

    我想上面的问题清楚地表明了我的观点:泛型允许你表达人类读者的意图。它们允许您编写更好的源代码;它们使编译器能够对您的输入进行某些类型的检查——安迪·特纳的另一个答案很好地总结了这一点

    这就是编程语言提供给您的任何抽象的全部要点:它们帮助程序员创建源代码,以简洁的方式表达“需要做什么”,使人类读者更容易理解正在发生的事情,以及为什么