简体   繁体   English

从泛型类型到相同类型的未经检查的强制转换

[英]Unchecked cast from generic type to the same type

The following code generates a warning Unchecked cast: 'T' to 'U' in IntelliJ IDEA:以下代码在 IntelliJ IDEA 中生成警告Unchecked cast: 'T' to 'U'

interface A {}
class B<T extends A, U extends A> {
    void f() {
        final T t = null;
        final U u = (U) t;
    }
}

This doesn't make sense to me, since T and U are defined as the same type.这对我来说没有意义,因为TU被定义为相同的类型。 What is the problem?问题是什么?

T and U are not defined as the same type. TU未定义为同一类型。 They are both defined as extends A , which means T and U can be unrelated classes that implement the A interface.它们都定义为extends A ,这意味着TU可以是实现A接口的无关类。 Hence the cast is not safe.因此演员表是不安全的。

The only safe cast you can do is to cast references of type T or U to type A .您可以做的唯一安全转换是将类型TU引用转换为类型A Of course you don't need such a cast.当然,你不需要这样的演员。 You can simply assign them to a variable of type A .您可以简单地将它们分配给A类型的变量。

While both T and U extend A , they are not the same type.虽然TU扩展了A ,但它们不是同一类型。 Hence you cannot cast from one to the other.因此你不能从一个转换到另一个。

Consider:考虑:

class D implements A {}
class E implements A {}
B<D, E> b;

You cannot cast from D to E.你不能从 D 投射到 E。

Parent:家长:

interface A {
} 

Child:孩子:

class B implements A {

}

class C implements A {

}

In the above example A is parent B and C.在上面的例子中,A 是父 B 和 C。

Example:例子:

The below code will works fine.下面的代码将正常工作。

  A a = new B();

  B b = (B)a;

This will trigger class Cast Exception.这将触发类 Cast Exception。

  B b = new B();

  C c = (C) b;

You can't type cast with your Siblings type.您不能使用 Siblings 类型进行类型转换。 This is because You may try to access the methods/properties that may present in the resultant class.这是因为您可能会尝试访问可能出现在结果类中的方法/属性。

Same thing can be to String,Integer,Object.同样的事情可以是字符串,整数,对象。 Object is parent对象是对象
Integer & String are the child for Object class but you cannot cast these classed. Integer 和 String 是 Object 类的子类,但您不能将这些分类。

    final T t = null;
    final U u = (U) t;

Although this is unchecked, this is actually safe, because null can be cast to any reference type without a ClassCastException .尽管这是未经检查的,但这实际上是安全的,因为null可以在没有ClassCastException情况下转换为任何引用类型。

However, the compiler doesn't consider the value of a non-null reference when you cast it: it's simply "some" T .但是,编译器在转换非空引用时不会考虑它的值:它只是“一些” T This is an example of where you, the programmer, know more about the types than the compiler, because you know that t == null , so you can legitimately ask the compiler to trust you by adding casts and @SuppressWarnings .这是一个例子,你,程序员,比编译器更了解类型,因为你知道t == null ,所以你可以通过添加强制转换和@SuppressWarnings合法地要求编译器信任你。

But if t were non-null, this wouldn't always be safe.但是如果t不为空,这并不总是安全的。 T and U are different types: they are "something that extends A " and "something (maybe the same, maybe not) that extends A ". TU有不同的类型:他们是“东西延伸A ”和“扩展的东西(也许是相同的,也许不是) A ”。

To make this a little bit more concrete, here's an equivalent example:为了使这更具体一点,这是一个等效的示例:

class B<T extends Serializable, U extends Serializable> {
  U method(T t) {
    return (U) t;
  }
}

String s = new B<Integer, String>().method(1);

This will fail with a ClassCastException , because an Integer isn't a String .这将因ClassCastException失败,因为Integer不是String

If you don't want them to be different types, remove one of them (and, of course, the cast).如果您不希望它们是不同类型,请删除其中之一(当然还有演员表)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM