简体   繁体   中英

How to convert List elements to it's super type?

Assume I have the following:

class MyType<T> {
    // ...
}

private void test() {
    Set<MyType<? extends Serializable>> in;
    Set<MyType<Serializable>> out; 
}

then the following assignment is illegal: out = new HashSet<>(in); also out.addAll(in) is illegal, because it cannot be implicitly converted. The following however is completely legal:

out = new HashSet<>();
for (MyType<? extends Serializable> s : in) {
    out.add((MyType<Serializable>) s);
}

Is there a more elegant way to do this in Java 7 without using an add-loop or dirty/uncheckable casts?

Is there a more elegant way to do this in Java 7 without using an add-loop or dirty/uncheckable casts?

No, because you're doing something which isn't type safe.

You're trying to treat a MyType<? extends Serializable> MyType<? extends Serializable> as a MyType<Serializable> - which it's not: a MyType<Serializable> is a MyType<? extends Serializable> MyType<? extends Serializable> , not the other way around.

For example, a MyType<String> is a MyType<? extends Serializable> MyType<? extends Serializable> , but it's not a MyType<Serializable> .

Unless you can provide a method on the MyType to do the cast (and you'll have an unchecked cast there), or otherwise provide a method to give you a MyType<Serializable> from a MyType<? extends Serializable> MyType<? extends Serializable> , you will just have to live with the unchecked cast elsewhere.


You haven't defined any methods on MyType , but let's say it's got a getter and a setter:

class MyType<T> {
  T field;
  void set(T field) { this.field = field; }
  T get() { return field; }
}

Now, let's assume that you've got this code:

MyType<String> str = new MyType<>();

If you cast this to a MyType<Serializable> , then you can invoke the setter with anything that implements Serializable :

MyType<Serializable> ser = (MyType<Serializable>) str;
ser.set(Integer.valueOf(0));

You're in trouble now, because:

String got = str.get();

will throw a ClassCastException .

The cast you claim is "absolutely safe" is not. It is only safe if there are no consumer methods on the class which take a parameter T ; and the compiler doesn't consider the existence of any methods to determine if something is type safe.

As such, this cast should generate a warning; if it doesn't, well, that doesn't mean it is actually safe, it just means that either the compiler didn't consider this case, or you are suppressing the warning.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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