Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 虽然我们可以使用对象Pojo,但为什么需要泛型类型然后是类型reasure_Java_Generics - Fatal编程技术网

Java 虽然我们可以使用对象Pojo,但为什么需要泛型类型然后是类型reasure

Java 虽然我们可以使用对象Pojo,但为什么需要泛型类型然后是类型reasure,java,generics,Java,Generics,我有这样的代码: public class Crate<T> { private T contents; public T emptyCrate() { return contents; } public void packCrate(T contents) { this.contents = contents; } } Crate crate = new Crate(); crate.packCr

我有这样的代码:

public class Crate<T> {
    private T contents;

    public T emptyCrate() {
        return contents;
    }

    public void packCrate(T contents)
    {
        this.contents = contents;
    }
}
Crate crate = new Crate();
crate.packCrate(0);
String contents = (String) crate.emptyCrate();

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

Java中的所有集合都是泛型。这是使用泛型的最好例子。例如,创建类列表。它将容纳哪些类型的对象?当您创建
List
类时,您不知道它将包含哪些类型,所以您使用泛型。当您使用
List
类时,您会说,您想要放入
整数
new List你看,java代码被翻译成字节码。那么你为什么不用字节码编写程序呢?它们还是会被翻译的?或者,确切地说,JIT编译器会在某个时候将大部分字节码转换成机器码。那么,你为什么坚持编写java源代码,而不是二进制机器码呢

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


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

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

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

Crate<Integer> intCrate = new Crate<>();
intCrate.packCrate(0);
Integer contents = intCrate.emptyCrate();
i、 e.有自动插入的强制转换。此外,隐式地,还有一个检查,检查
packCrate
的参数是否与
Integer
兼容,因此您无法写入:

intCrate.packCrate("hello");
现在,您可以在不使用泛型的情况下执行此操作,您可以自己放入这些强制转换,但编译器无法帮助您了解放入
板条箱的内容

public class Crate<T> {
    private T contents;

    public T emptyCrate() {
        return contents;
    }

    public void packCrate(T contents)
    {
        this.contents = contents;
    }
}
Crate crate = new Crate();
crate.packCrate(0);
String contents = (String) crate.emptyCrate();
这将在运行时失败,因为板条箱包含一个
整数
,而不是
字符串


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

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

Crate<Integer> cr;
Object o;

cr.packCrate(o);  // compilation error here
板条箱cr;
对象o;
cr.packCrate(o);//此处编译错误
它还可以声明用作参数的任何类都将实现某些方法:

Interface I {
    void myMethod();
}

class Crate<T extends I> {
    private T contents;
    ...
    public void applyMethod() {
        contents.myMethod();      // T shall implement myMethod
    }
}
接口I{
void myMethod();
}
分类板条箱{
私有内容;
...
public void applyMethod(){
contents.myMethod();//T应实现myMethod
}
}

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

它将变成什么并不重要

泛型保证编译类型的类型安全(修复编译时错误比修复运行时错误容易得多)


它还消除了强制转换,并启用了实现泛型算法的能力。

得到了答案。如果我们创建一个对象pojo,那么编译时的子方法是隐藏的,因为如果您希望您的
板条箱
包含
整数
字符串
,无论什么,您都必须强制转换
清空速率()的结果
整数
字符串
或其他任何类型-并且您必须记住它包含的数据类型。如果您尝试插入错误的类型,编译器也会提示您错误。而且不仅是在运行时。泛型是程序员对类型安全的保障。在java 1.5出现之前发生的许多错误,但它不是“消除强制类型转换”,但它消除了自己编写强制类型转换的需要。我想说泛型省略强制类型转换,而不是消除它们。