2015-12-18 37 views
2
Test1.java 

public class Test1 { 


    public static void main(String[] args) { 
     Box stringBox = new Box<>(); 
     stringBox.set("Hello World"); 
     Box<Integer> rawBox = stringBox; 
     System.out.println(rawBox.get()); 
     rawBox.set(8); 
     System.out.println(rawBox.get()); 
     rawBox.show(); 


    } 

} 


Box.java 

public class Box<String1> { 

    private String1 t; 
    private String1 temp1 =(String1) "temp"; 

     public void set(String1 d) { this.t =d; } 

     public String1 get() 
     { 
      return this.t; 
     } 

     public void show() 
     { 
      System.out.println(t.getClass()); 
      System.out.println(temp1); 
      System.out.println(temp1.getClass()); 
     } 


} 

我的问题: 这里rawBox是一个通用整数类型的那么它怎么能存储的“Hello World”哪一个字符串。我已经尝试过很多网站和oracle docx,但没有什么可以作为这个问题的完整答案。在先进的Thanx。Java泛型,我遇到一些麻烦对象铸件通用

+0

'String1'是什么类型?这与'String'不一样。此外,你的“Box”类不是通用的。 – hotzst

+0

String1是通用类型的独立名称。 为什么box.java不是泛型的? –

回答

2

名称String1定义了类型变量的名称。这只是编译时存放变量类型的“变量”的名称。它在运行时不存在。为了解Box类在其字段中的真正含义,您可以想象,替代泛型类型String1您有Object类型。当然Object变量可以容纳任何类型。

,以便类等同于:

public class Box { 

    private Object t; 
    private Object temp1 = "temp"; 

     public void set(Object d) { this.t =d; } 
... 
} 
+0

在第10行 - > System.out.println(rawBox.get()); 参考rawBox是一个Integer类型的generice,但它不会抛出任何错误,并且简单打印“Hello world”。 我的问题是为什么rawBox显示这样的行为! –

+0

它不应该在这里抛出任何异常,因为'java'在这里自动调用'toString()'方法。阅读'JLS'。 – Andremoniy

0

如果哟真的要停止整数盒得到分配到字符串中,更改代码,如下所示(Box<String> stringBox = new Box<String>();

public static void main(String[] args) { 
    //Box stringBox = new Box<>(); 
    Box<String> stringBox = new Box<String>(); 
    stringBox.set("Hello World"); 
    Box<Integer> rawBox = stringBox; 
    System.out.println(rawBox.get()); 
    rawBox.set(8); 
    System.out.println(rawBox.get()); 
    rawBox.show(); 
} 

现在您收到以下错误

Test1.java:6: error: incompatible types 
    Box<Integer> rawBox = stringBox; 

如果您保留原始代码,请在警告下使用其他标志进行编译。

javac -Xlint:unchecked Test1.java 
Test1.java:4: warning: [unchecked] unchecked call to set(String1) as a member of the raw type Box 
       stringBox.set("Hello World"); 
          ^
    where String1 is a type-variable: 
    String1 extends Object declared in class Box 
Test1.java:5: warning: [unchecked] unchecked conversion 
     Box<Integer> rawBox = stringBox; 
          ^
    required: Box<Integer> 
    found: Box 
Test1.java:17: warning: [unchecked] unchecked cast 
    private String1 temp1 =(String1) "temp"; 
            ^
    required: String1 
    found: String 
    where String1 is a type-variable: 
    String1 extends Object declared in class Box 
3 warnings 

的通用盒是接受任何对象类型的,因此它允许String, String1 and Integer。如果你不想玩普通的Box,总是定义正确的对象类型,当发生不匹配时你会得到编译错误。

+0

我不想编辑任何东西,这个程序运行良好,并提供以下输出。 临时 的Hello World 临时类java.lang.Integer 类java.lang.String 我的问题是,为什么rawBox是打印的“Hello World”,当它的通用整型的! –

+0

你的程序运行良好,没有逻辑错误。但是您可以使用javac -Xlint:unchecked查看相同代码的警告。 –

+0

是的,我知道所有警告,但我的问题是,为什么rawBox打印“Hello World”时,它是一个Integer类型的泛型! –

2

第一次创建一个对话框:

Box stringBox = new Box<>(); 

你忽略了仿制药。这使您可以设置一个Object,其中包含String。

在此之后,您将stringBox设置为等于rawBox,这是允许的,因为它是相同的类型(整数是对象)。 如果您但是没有忽视仿制药,并说:

Box<String> stringBox = new Box<>(); 

当你到达这条线,你会发现一个RuntimeException:

Box<Integer> rawBox = stringBox; 

泛型使他们不再是同一类型的,其实错误说正是这一点:

incompatible types: scratchpad.Box<java.lang.String> cannot be converted to scratchpad.Box<java.lang.Integer> 

你应该尝试,之后设置一个字符串值,例如:

​​

您会发现它也会导致RunTimeException,因为您试图将String设置为Integer泛型。

+0

上面编写的程序不会引发任何异常/错误。但是,我不明白为什么当rawBox是一个整数类型的泛型时,为什么sysout(rawBox.get())返回给我“Hello World”! –

+0

rawBox是指向原始字符串的引用。因此,在使用rawBox时,实际上使用的是不是Integer类型的stringBox。 您没有实例化一个Integer泛型Box,您只设置了一个引用,它接受了非泛型Box:stringBox – Propagandian

1

当你说,

Box stringBox = new Box<>(); 

你实际上是说什么都可以进入Box实例。

后你说,

Box<Integer> rawBox = stringBox; 

你是说只有整数将从这一点是允许的。

Java中的泛型不是“真正的泛型”,它是语法糖。当您引用先前声明的通用实例时,如果其中包含的对象对新通用引用有效,则VM将不会进行验证。

感兴趣的是

private String1 temp1 = (String1) "temp"; 

正在发生的事情在这里,我最好的猜测,是因为仿制药是不是它的真实的形式,编译允许这种情况发生,并保持真正正确的类型正在铸造的价值。

所以实际上盒看起来是这样的:

public class Box { 
    private Object t; 
    private Object temp1 =(Object) "temp"; 
    //..... 
} 

像@Andremoniy说。

+0

我尝试反编译Box.class,但它仅存储String类型的值,而不是Object类型。 –

相关问题