Pay attention to the objects of comparison
A is a subclass of B. A and B are comparing
And List<A> is a subclass of List<B> and is compared with List
You can use definitions like List<? extend b> to perform limited operations
Object inheritance represents an ‘is-a’ relationship. If two objects A and B can be expressed as ‘B is A’, it means that B can inherit A. The successor can also be understood as the specialization of the inherited, because in addition to the characteristics of the inherited, it also has its own unique personality.
Parent class and subclass, or base class and derived class, where the subclass inherits all the characteristics of the parent class and also defines new characteristics.
Generics in Java are implemented through Type erasure
Generics in Java are basically implemented at the compiler level. The type information in generics is not included in the generated Java bytecode. Type parameters added when using generics will be removed by the compiler during compilation. This process is called type erasure.
List <A> 和 List <B> 在编译完成以后,实际上指向的是同一份字节码
并不存在 List <A> 或者 List <B> 这2种类型 ,当然就更谈不上什么子类的问题了.
The following is for reference only. I am not familiar with C++
Aren’t you confused with C++ templates?
Generics in C++ are implemented differently
A lot of answers don’t get to the point. . Let me add some content. Two concepts are involved here: covariance and contravariance. (Covariance vs. Contravariance)
In short, if the List<S> composite type is covariant, then if S is a subclass of T, then List<S> is also a subclass of List<T>. If List<S> is contravariant, the result is reversed, and List<T> will become a subclass of List<S>.
But generics in Java do not implement either of the above two behaviors. . Java's generics are invariant (Invariance).
Why is it designed like this? Let’s look at an array example first. In Java, arrays are covariant, so Integer[] is a subclass of Number[]. So we can write code like this:
Integer[] a = new Integer[3];
Number[] b = a; // a的类型是Integer[],是Number[]的子类
b[0] = 3.14; // 运行时错误
Java’s Type Safety guarantee has been broken. Java will save the type of the array elements (Reification) to ensure that this illegal operation can be detected at runtime.
Assuming that List is covariant, then the code to put Float into Integer is as follows:
List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // li的类型是List<Integer>,属于List<Number>的子类
ln.add(new Float(3.1415)); // 不会有错误
will run. And @dkmeteor also mentioned that Java's generics use type erasure, so there is no guarantee whether a Float will be stuffed into the List, because all the List sees at runtime are Objects. So to prevent this kind of thing from happening, Java's generics are immutable.
Is there any way to use covariant or contravariant generics in Java? The answer is yes, you need to add wildcard to the statement:
// 1.协变范例
List<? extends Number> num = new List<Double>();
// 2.逆变范例
List<? super Number> num = new List<Object>();
But in the first case, you cannot call the function with ? in the parameter, for example:
class Container<E> {
E data;
public set(E data) {
this.data = data;
}
public E get(E data) {
return data;
}
}
// 某方法中
Container<? extends Number> num = new Container<Double>();
num.set(new Float(3)); // 编译时错误
This is also to ensure Type Safety. Cannot pass Float to Container<Double>.
Similarly, when inverting, you cannot call a function with a return value of ? unless the variable type that accepts the return value is Object.
Container<? super Number> num2;
Number res = num2.get(); // 编译时错误
Part of the source: http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
Pay attention to the objects of comparison
A is a subclass of B. A and B are comparing
And
List<A>
is a subclass ofList<B>
and is compared with ListYou can use definitions like
List<? extend b>
to perform limited operationsBecause they are both List classes and there is no inheritance relationship
Object inheritance represents an ‘is-a’ relationship. If two objects A and B can be expressed as ‘B is A’, it means that B can inherit A. The successor can also be understood as the specialization of the inherited, because in addition to the characteristics of the inherited, it also has its own unique personality.
Parent class and subclass, or base class and derived class, where the subclass inherits all the characteristics of the parent class and also defines new characteristics.
A subclass of
List<A>
isclass XXX extends List<A>
Generics in Java are implemented through Type erasure
The following is for reference only. I am not familiar with C++
Aren’t you confused with C++ templates?
Generics in C++ are implemented differently
Because
List<A>.class
is not true.Generic
A lot of answers don’t get to the point. . Let me add some content. Two concepts are involved here: covariance and contravariance. (Covariance vs. Contravariance)
In short, if the
List<S>
composite type is covariant, then ifS
is a subclass ofT
, thenList<S>
is also a subclass ofList<T>
. IfList<S>
is contravariant, the result is reversed, andList<T>
will become a subclass ofList<S>
.But generics in Java do not implement either of the above two behaviors. . Java's generics are invariant (Invariance).
Why is it designed like this? Let’s look at an array example first. In Java, arrays are covariant, so
Integer[]
is a subclass ofNumber[]
. So we can write code like this:Java’s Type Safety guarantee has been broken. Java will save the type of the array elements (Reification) to ensure that this illegal operation can be detected at runtime.
Assuming that List is covariant, then the code to put Float into Integer is as follows:
will run. And @dkmeteor also mentioned that Java's generics use type erasure, so there is no guarantee whether a Float will be stuffed into the List, because all the List sees at runtime are Objects. So to prevent this kind of thing from happening, Java's generics are immutable.
Is there any way to use covariant or contravariant generics in Java? The answer is yes, you need to add wildcard to the statement:
But in the first case, you cannot call the function with
?
in the parameter, for example:This is also to ensure Type Safety. Cannot pass
Float
toContainer<Double>
.Similarly, when inverting, you cannot call a function with a return value of
?
unless the variable type that accepts the return value is Object.Part of the source: http://www.ibm.com/developerworks/cn/java/j-jtp01255.html