管理通用外部 class 及其内部通用内部 class 实例化实例和声明各自引用的规则是什么?
What are rules governing instantiating instances of generic outer class and its inner generic inner class and declaring respective references?
1) 为什么obj4,obj6,obj7编译报错,obj5没问题?我在哪里可以阅读有关使用此类通用耦合外-内 classes 进行监管的规则?我没有找到任何直截了当的东西。
当我不为 obj3 中的 Inner class 提供任何类型参数时,它很好(而 Inner class 需要为其 S 类型的 fld3 字段提供一些东西),但是当我做同样的事情并且不为 Outer class 提供类型时 - 它不编译(obj4) - 尽管可以隐含对象...
2) 此外,为什么obj10 编译正常,但obj11 却失败了?在 obj10 行中,我还写了 outerInstance.new Inner<>(),暗示对于 Inner,S 是对象。但这对内部来说不是问题,但同样 "trick" 是外部问题...
//in Class A of package com.sth
public class MyGen<T> {
T fld1;
class GenInner<S> {
T fld2;
S fld3;
}
// within main of Class Driver of same package com.sth
MyGen.GenInner obj1 = new MyGen<String>().new GenInner<Integer>();
MyGen.GenInner obj2 = new MyGen<String>().new GenInner<>();
MyGen.GenInner obj3 = new MyGen<String>().new GenInner();
//MyGen.GenInner obj4 = new MyGen().new GenInner<String>(); //ERR !
MyGen.GenInner obj5 = new MyGen<>().new GenInner<String>();
//MyGen<String>.GenInner obj6; // ERR
//MyGen.GenInner<String> obj7; // ERR
MyGen<String>.GenInner<Integer> obj8;
MyGen.GenInner obj9;
MyGen<String>.GenInner<Integer> obj10 = new MyGen<String>().new GenInner<>();
//Type mismatch: cannot convert from MyGen<Object>.GenInner<Integer> to MyGen<String>.GenInner<Integer>
//MyGen<String>.GenInner<Integer> obj11 = new MyGen<>().new GenInner<Integer>(); // ERR!
这些答案与我的问题有关,但没有提供任何线索:
- Answer 2
- Answer 3
- Answer 4
- Answer 5
不编译的例子大多是稀有类型的例子。 (此外,正如 John 在评论中指出的那样,obj3
示例也不应编译。)
A raw type 是通过使用没有附带类型参数列表的泛型类型形成的类型(例如 Set
,与 Set<Float>
相对)。 稀有 类型是当你有一个通用外部 class 和通用内部 class 时,其中一个是原始的,另一个不是。
More precisely, a raw type is defined to be one of:
The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
An array type whose element type is a raw type.
A non-static
member type of a raw type R
that is not inherited from a superclass or superinterface of R
.
(请注意,粗体表示如果您有原始类型 MyGen
,那么它的非 static
成员 class GenInner
也必须是原始类型, 所以没有 MyGen.GenInner<String>
.)
这样的东西
Another implication of the rules above is that a generic inner class of a raw type can itself only be used as a raw type:
class Outer<T>{
class Inner<S> {
S s;
}
}
It is not possible to access Inner
as a partially raw type (a "rare" type):
Outer.Inner<Double> x = null; // illegal
Double d = x.s;
because Outer
itself is raw, hence so are all its inner classes including Inner
, and so it is not possible to pass any type arguments to Inner.
It is a compile-time error to pass type arguments to a non-static
type member of a raw type that is not inherited from its superclasses or superinterfaces.
It is a compile-time error to attempt to use a type member of a parameterized type as a raw type.
This means that the ban on "rare" types extends to the case where the qualifying type is parameterized, but we attempt to use the inner class as a raw type:
Outer<Integer>.Inner x = null; // illegal
This is the opposite of the case discussed above. There is no practical justification for this half-baked type. In legacy code, no type arguments are used. In non-legacy code, we should use the generic types correctly and pass all the required type arguments.
带有 obj11 = new MyGen<>().new GenInner<Integer>()
的示例并不罕见。它看起来像是钻石类型推断的常规失败,因为表达式 new MyGen<>()
没有分配给任何东西。在没有分配的情况下,通常假定 Object
。 (从技术上讲,它可以是类型变量的上限,在这种情况下是 Object
。)
此外,虽然与手头的问题没有直接关系,但以下是新代码中实际应该使用的仅有的两种形式:
MyGen<String>.GenInner<Integer> ok1 = new MyGen<String>().new GenInner<Integer>();
MyGen<String>.GenInner<Integer> ok2 = new MyGen<String>().new GenInner<>();
所有其他(编译)使用原始类型,不鼓励使用原始类型。
1) 为什么obj4,obj6,obj7编译报错,obj5没问题?我在哪里可以阅读有关使用此类通用耦合外-内 classes 进行监管的规则?我没有找到任何直截了当的东西。
当我不为 obj3 中的 Inner class 提供任何类型参数时,它很好(而 Inner class 需要为其 S 类型的 fld3 字段提供一些东西),但是当我做同样的事情并且不为 Outer class 提供类型时 - 它不编译(obj4) - 尽管可以隐含对象...
2) 此外,为什么obj10 编译正常,但obj11 却失败了?在 obj10 行中,我还写了 outerInstance.new Inner<>(),暗示对于 Inner,S 是对象。但这对内部来说不是问题,但同样 "trick" 是外部问题...
//in Class A of package com.sth
public class MyGen<T> {
T fld1;
class GenInner<S> {
T fld2;
S fld3;
}
// within main of Class Driver of same package com.sth
MyGen.GenInner obj1 = new MyGen<String>().new GenInner<Integer>();
MyGen.GenInner obj2 = new MyGen<String>().new GenInner<>();
MyGen.GenInner obj3 = new MyGen<String>().new GenInner();
//MyGen.GenInner obj4 = new MyGen().new GenInner<String>(); //ERR !
MyGen.GenInner obj5 = new MyGen<>().new GenInner<String>();
//MyGen<String>.GenInner obj6; // ERR
//MyGen.GenInner<String> obj7; // ERR
MyGen<String>.GenInner<Integer> obj8;
MyGen.GenInner obj9;
MyGen<String>.GenInner<Integer> obj10 = new MyGen<String>().new GenInner<>();
//Type mismatch: cannot convert from MyGen<Object>.GenInner<Integer> to MyGen<String>.GenInner<Integer>
//MyGen<String>.GenInner<Integer> obj11 = new MyGen<>().new GenInner<Integer>(); // ERR!
这些答案与我的问题有关,但没有提供任何线索:
- Answer 2
- Answer 3
- Answer 4
- Answer 5
不编译的例子大多是稀有类型的例子。 (此外,正如 John 在评论中指出的那样,obj3
示例也不应编译。)
A raw type 是通过使用没有附带类型参数列表的泛型类型形成的类型(例如 Set
,与 Set<Float>
相对)。 稀有 类型是当你有一个通用外部 class 和通用内部 class 时,其中一个是原始的,另一个不是。
More precisely, a raw type is defined to be one of:
The reference type that is formed by taking the name of a generic type declaration without an accompanying type argument list.
An array type whose element type is a raw type.
A non-
static
member type of a raw typeR
that is not inherited from a superclass or superinterface ofR
.
(请注意,粗体表示如果您有原始类型 MyGen
,那么它的非 static
成员 class GenInner
也必须是原始类型, 所以没有 MyGen.GenInner<String>
.)
Another implication of the rules above is that a generic inner class of a raw type can itself only be used as a raw type:
class Outer<T>{ class Inner<S> { S s; } }
It is not possible to access
Inner
as a partially raw type (a "rare" type):Outer.Inner<Double> x = null; // illegal Double d = x.s;
because
Outer
itself is raw, hence so are all its inner classes includingInner
, and so it is not possible to pass any type arguments to Inner.
It is a compile-time error to pass type arguments to a non-
static
type member of a raw type that is not inherited from its superclasses or superinterfaces.It is a compile-time error to attempt to use a type member of a parameterized type as a raw type.
This means that the ban on "rare" types extends to the case where the qualifying type is parameterized, but we attempt to use the inner class as a raw type:
Outer<Integer>.Inner x = null; // illegal
This is the opposite of the case discussed above. There is no practical justification for this half-baked type. In legacy code, no type arguments are used. In non-legacy code, we should use the generic types correctly and pass all the required type arguments.
带有 obj11 = new MyGen<>().new GenInner<Integer>()
的示例并不罕见。它看起来像是钻石类型推断的常规失败,因为表达式 new MyGen<>()
没有分配给任何东西。在没有分配的情况下,通常假定 Object
。 (从技术上讲,它可以是类型变量的上限,在这种情况下是 Object
。)
此外,虽然与手头的问题没有直接关系,但以下是新代码中实际应该使用的仅有的两种形式:
MyGen<String>.GenInner<Integer> ok1 = new MyGen<String>().new GenInner<Integer>();
MyGen<String>.GenInner<Integer> ok2 = new MyGen<String>().new GenInner<>();
所有其他(编译)使用原始类型,不鼓励使用原始类型。