有 Java 编程相关的问题?

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

带有泛型的java动态转换

以下代码编译并执行时不会出错:

public class Main {
    public static void main(String[] args) {
        Box <Integer, String> box = new Box<>(30, "Hallo");
        System.out.println(box);
        box.swapItems(box);
        System.out.println(box);
    }
}

public class Box <F, S> {    
    F first;
    S second;

    public Box(F first, S second) {
        this.first = first;
        this.second = second;
    }

    void swapItems(Box <F,S> box){
        F temp = box.first;
        box.first = (F) box.second;
        box.second = (S) temp;
    }

    @Override
    public String toString() {
       return "Box{first=" + first +", second=" + second +'}';
    }
}

产出:

>>> Box {first = 30, second = Hallo}
>>> Box {first = Hallo, second = 30}

虽然乍一看这没问题,但(对我来说)却不是。事实上,发生了很多非常奇怪的事情

  1. F temp = box.first;此行将temp设置为整数。到目前为止还不错
  2. box.first = (F) box.second;但是,不允许执行这一行,除非它执行。确切地说,我们正在铸造:int a = (int) "Hello";的各自,这显然是不好的。所以我的问题是为什么它在这里工作?为什么我们让box.first的类型在运行时动态更改,而在其他情况下这是禁止的
  3. box.second = (S) temp;更糟糕的是,这一行分别执行了{}的操作,虽然这在语法上是错误的,但它至少具有直观意义,因为30可以变成“30”。。。但是,发生的情况是box.second的类型变为整数,并将30分配给它。这对我来说毫无意义,整数被转换为字符串,结果接收变量的类型被动态更改为整数

此外,在运行这段代码之后,只有当您尝试在classcast异常中执行与其变量one的类型相关的操作时(如预期的那样),才能继续使用box,就好像什么也没发生一样

我知道避免这种情况的解决方案是使swapItems成为静态的,并使用另一个泛型类型变量来强制作为参数传递的框的类型之间的关系(例如T void swapItems(Box <T,T> box){..}),但这里的问题是:为什么第2行和第3行(上面使用的符号)工作?下面发生了什么,使得编译器/JVM认为这是一个可接受的行执行?我错过什么了吗

编辑:

从上面链接的重复答案中,可以将我的问题的答案总结为: Java泛型只是铸造对象的语法糖


共 (0) 个答案