在 Java 中铸造数组过程? (协方差和 [LObject)
Casting array process in Java? (covariance and [LObject)
我的问题是 Java 中的铸造过程究竟如何?
假设我们有
User[] users = new User[2];//<-- here we get at runtime [LUser class
Object[] objects = (Object[]) users;//<-- here we get at runtime [LObject class
public class [LUser extends Object implements Serializable, Cloneable{
}
public class [LObject extends Object implements Serializable, Cloneable{
}
我知道由于 User 是 Object 的数组协变性,User[] 也是 Object[]。但是关于 class 创建([LUser 和 [LObject 问题)的解释破坏了我对协方差的理解。因为如果我们注意到 [LUser 和 [LObject
User[] users = new User[2];
Object[] objects = (Object[]) users;
//<-- here we cast [LUser to [LObject but [LUser doesn't extends [Lobject
那么铸造过程究竟如何呢?
可能问题看起来很疯狂,但从逻辑上讲我得到了这个结果。在最坏的情况下,我可以认为在语法上 Java 将 User[] 转换为 Object[] 但那时为什么我们需要像 [LObject, [LUser
这样的对象创建
根据JLS 4.10.3. Subtyping among Array Types (link ) :
The following rules define the direct supertype relation among array types:
If S
and T
are both reference types, then S[]
>1 T[]
iff S
>1 T
.
Object
>1 Object[]
Cloneable
>1 Object[]
java.io.Serializable
>1 Object[]
以上意思如下。当然你不能这么写,但那是 Java 数组子类型化规则的等价物。
// Rule #2 Rule #3 Rule #4
class Object[] extends Object implements Cloneable, Serializable {
}
// Rule #1
class User[] extends Object[] {
}
更新
The members of an array type are all of the following:
The public
final
field length
, which contains the number of components of the array. length
may be positive or zero.
The public
method clone
, which overrides the method of the same name in class Object
and throws no checked exceptions. The return type of the clone
method of an array type T[]
is T[]
.
A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.
All the members inherited from class Object
; the only method of Object
that is not inherited is its clone
method.
那就意味着:
class Object[] extends Object implements Cloneable, Serializable {
public final int length = /*value from array creation*/;
public Object[] clone() {
try {
return (Object[]) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}
}
}
class User[] extends Object[] {
public User[] clone() {
return (User[]) super.clone();
}
}
我的问题是 Java 中的铸造过程究竟如何? 假设我们有
User[] users = new User[2];//<-- here we get at runtime [LUser class
Object[] objects = (Object[]) users;//<-- here we get at runtime [LObject class
public class [LUser extends Object implements Serializable, Cloneable{
}
public class [LObject extends Object implements Serializable, Cloneable{
}
我知道由于 User 是 Object 的数组协变性,User[] 也是 Object[]。但是关于 class 创建([LUser 和 [LObject 问题)的解释破坏了我对协方差的理解。因为如果我们注意到 [LUser 和 [LObject
User[] users = new User[2];
Object[] objects = (Object[]) users;
//<-- here we cast [LUser to [LObject but [LUser doesn't extends [Lobject
那么铸造过程究竟如何呢? 可能问题看起来很疯狂,但从逻辑上讲我得到了这个结果。在最坏的情况下,我可以认为在语法上 Java 将 User[] 转换为 Object[] 但那时为什么我们需要像 [LObject, [LUser
这样的对象创建根据JLS 4.10.3. Subtyping among Array Types (link
The following rules define the direct supertype relation among array types:
If
S
andT
are both reference types, thenS[]
>1T[]
iffS
>1T
.
Object
>1Object[]
Cloneable
>1Object[]
java.io.Serializable
>1Object[]
以上意思如下。当然你不能这么写,但那是 Java 数组子类型化规则的等价物。
// Rule #2 Rule #3 Rule #4
class Object[] extends Object implements Cloneable, Serializable {
}
// Rule #1
class User[] extends Object[] {
}
更新
The members of an array type are all of the following:
The
public
final
fieldlength
, which contains the number of components of the array.length
may be positive or zero.The
public
methodclone
, which overrides the method of the same name in classObject
and throws no checked exceptions. The return type of theclone
method of an array typeT[]
isT[]
.A clone of a multidimensional array is shallow, which is to say that it creates only a single new array. Subarrays are shared.
All the members inherited from class
Object
; the only method ofObject
that is not inherited is itsclone
method.
那就意味着:
class Object[] extends Object implements Cloneable, Serializable {
public final int length = /*value from array creation*/;
public Object[] clone() {
try {
return (Object[]) super.clone();
} catch (CloneNotSupportedException e) {
throw new InternalError(e.getMessage());
}
}
}
class User[] extends Object[] {
public User[] clone() {
return (User[]) super.clone();
}
}