Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.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 初始化类本身中的泛型类型字段_Java_Class_Generics_Field_Instance - Fatal编程技术网

Java 初始化类本身中的泛型类型字段

Java 初始化类本身中的泛型类型字段,java,class,generics,field,instance,Java,Class,Generics,Field,Instance,这是代码 public class Dog { } public class Bird { } public class Animal< T > { T field1 = (T) new Bird(); // unchecked cast : Bird to T public void display() { System.out.println(field1); } } 主课 public static void main

这是代码

public class Dog {

}


public class Bird {

}


public class Animal< T > {
    T field1 = (T) new Bird();  // unchecked cast : Bird to T

    public void display() {
        System.out.println(field1);
    }
}

主课

public static void main(){
    Animal<Dog> animal = new Animal();
    animal.display();   // I was expecting run time error here

}
publicstaticvoidmain(){
动物=新动物();
animal.display();//我在这里预期运行时错误
}

没有错误,因为代码仍然“有效”。Java泛型是一种处理对象强制转换和改进类型检查的奇特方法。每次使用泛型时,在编译代码时,Java都会以显式转换的方式转换它们。主要原因与引入泛型之前遗留的Java版本有关,所以Java像处理“Object”类一样处理它们,然后在需要时为您强制转换它们

例如,在.java文件中编写以下代码:

String hello = new String();
ArrayList<String> list = new ArrayList<>();
list.add(hello);

Object noCastRequired = list.get(0);
String castRequired = list.get(0);
String hello=new String();
ArrayList=新建ArrayList();
添加(hello);
Object nocasterequired=list.get(0);
String casterequired=list.get(0);
Java将在其相对的.class文件中写入:

String hello = new String();
ArrayList<String> list = new ArrayList();
list.add(hello);
Object noCastRequired = list.get(0);
String castRequired = (String)list.get(0);
String hello=new String();
ArrayList=新建ArrayList();
添加(hello);
Object nocasterequired=list.get(0);
String casterequired=(String)list.get(0);
如果要检查编译后的代码,可以看到该表达式仍然是有效的代码语句,但如果在需要“type”的方法中尝试“使用”该字段,则会出现错误和问题;print语句接受一个对象类a参数,所以Java不会强制转换它

例如:

class Scratch {
    public static void main(String[] args) {
        Root<FirstLevel> correct = new Root<>();

        Root<FirstLevelChild> iAmNotValid = new Root<>(); // No error
        Root<SecondLevel> iAmNotValidToo = new Root<>(); // No error

        System.out.println(correct.field.first); // Ok
        System.out.println(iAmNotValid.field.first); // Ko, because java.lang.ClassCastException: FirstLevel cannot be cast to FirstLevelChild
        System.out.println(iAmNotValidToo.field.second);
    }


}

class Root<T> {
    public T field = (T) new FirstLevel();
}

class FirstLevel {
    public String first = "First";
}

class SecondLevel {
    public String second = "Second";
}

class FirstLevelChild extends FirstLevel {
}
类刮擦{
公共静态void main(字符串[]args){
根正确=新根();
Root iAmNotValid=new Root();//无错误
Root iAmNotValidToo=新根();//无错误
System.out.println(correct.field.first);//确定
System.out.println(iAmNotValid.field.first);//Ko,因为java.lang.ClassCastException:FirstLevel不能强制转换为FirstLevelChild
System.out.println(iAmNotValidToo.field.second);
}
}
类根{
公共T字段=(T)新的第一级();
}
一级{
公共字符串first=“first”;
}
班级二级{
公共字符串second=“second”;
}
类FirstLevelChild扩展了FirstLevel{
}

问题是什么?您面临什么问题?这正是“unchecked cast”警告告诉您的,在运行时不会检查此构造的有效性。一些构造可能会失败,而另一些则不会,这使得这个问题变得如此严重。它可能会在远离堆污染最初发生的代码的地方失败。好的,在根类中,“new FirstLevel()”被强制转换为T。这意味着什么。假设在main类中,如果您提供实际参数作为与FirstLevel类不相关的其他类,那么它不应该给我错误。当您提供与FirstLevel不相关的类(如Root)时,代码对于编译仍然有效,因为Java将在Object中转换t,所以t field=(t)new FirstLevel()将是对象字段=新的FirstLevel()。当我打算在需要T类型的地方使用“field”时,将抛出ClassCastException,因为Java将把它放在.class文件(SecondLevel)字段中。即使您使用与FirstLevel相关的类(如FirstLevelChild),也会引发此运行时错误,因为字段始终是“FirstLevel”对象,所以(FirstLevelChild)字段不是有效的强制转换;你能提供我的链接,让我可以阅读更多关于这个。这将对我很有帮助您可以阅读或阅读任何Oracle Java参考book@sparshgoyal答案对你有帮助吗?
class Scratch {
    public static void main(String[] args) {
        Root<FirstLevel> correct = new Root<>();

        Root<FirstLevelChild> iAmNotValid = new Root<>(); // No error
        Root<SecondLevel> iAmNotValidToo = new Root<>(); // No error

        System.out.println(correct.field.first); // Ok
        System.out.println(iAmNotValid.field.first); // Ko, because java.lang.ClassCastException: FirstLevel cannot be cast to FirstLevelChild
        System.out.println(iAmNotValidToo.field.second);
    }


}

class Root<T> {
    public T field = (T) new FirstLevel();
}

class FirstLevel {
    public String first = "First";
}

class SecondLevel {
    public String second = "Second";
}

class FirstLevelChild extends FirstLevel {
}