简体   繁体   English

具有通用属性的 Java 枚举

[英]Java enum with generic attributes

I have been trying to create enum that contains generic attribute, for example:我一直在尝试创建包含通用属性的枚举,例如:

public enum SomeEnum {
    SOME_VALUE_1(SomeValue1.class),
    SOME_VALUE_2(SomeValue2.class);

    private final Class<T extends SomeValue> className;
}

SomeValue1 and SomeValue2 classes implement SomeValue interface. SomeValue1SomeValue2类实现SomeValue接口。 For some reason <T extends SomeValue> is marked with "Unexpected bound" error.出于某种原因, <T extends SomeValue>被标记为“意外绑定”错误。 If I replace T with ?如果我将T替换为? , there is no error. ,没有错误。 But it is still puzzling me why it is happening when I use T .但它仍然让我感到困惑,为什么当我使用T时会发生这种情况。

Any help would be highly appreciated.任何帮助将不胜感激。

When you use T extends SomeValue in this way, you are referencing a type variable T that isn't defined, and you aren't allowed to define a type variable there.当您以这种方式使用T extends SomeValue时,您正在引用一个未定义的类型变量T ,并且不允许您在那里定义一个类型变量。 Only on type variable declarations are you allowed to define a bound such as T extends SomeValue .只有在类型变量声明中,您才允许定义诸如T extends SomeValue之类的界限。

On an interface or class, you could define T with the bound you want, but not on an enum .在接口或 class 上,您可以使用所需的边界定义T ,但不能在enum上定义。 Enums are not allowed to be generic in Java.在 Java 中不允许枚举是通用的。

You are probably getting the same error on the constructor you haven't shown that accepts a Class<T extends SomeValue> to assign to className .您可能在未显示的构造函数上遇到相同的错误,该构造函数接受Class<T extends SomeValue>分配给className The same reason applies here too.同样的原因在这里也适用。

Using ? extends SomeValue使用? extends SomeValue ? extends SomeValue is an upper-bounded wildcard. ? extends SomeValue是一个上限通配符。 It basically means "a specific yet unknown type that is SomeValue or a subtype".它基本上意味着“一种特定但未知的类型,即SomeValue或子类型”。 This is appropriate here, because all you care about here is that the Class is for SomeValue or some implementation class.这在这里是合适的,因为您在这里关心的是Class用于SomeValue或某些实现 class。

<? extends SomeClass> <? extends SomeClass> and <T extends SomeClass> are two very different syntaxes. <? extends SomeClass><T extends SomeClass>是两种截然不同的语法。

The first is a wildcard bound , part of a type argument :第一个是通配符绑定,是类型参数的一部分:

TypeArguments:
  < TypeArgumentList >
TypeArgumentList:
  TypeArgument {, TypeArgument}
TypeArgument:
  ReferenceType 
  Wildcard
Wildcard:
  {Annotation} ? [WildcardBounds]
WildcardBounds:
  extends ReferenceType 
  super ReferenceType

The second is a type bound , part of a type parameter :第二个是类型绑定类型参数的一部分:

TypeParameter:
  {TypeParameterModifier} Identifier [TypeBound]
TypeParameterModifier:
  Annotation
TypeBound:
  extends TypeVariable 
  extends ClassOrInterfaceType {AdditionalBound}

What's the difference between a type parameter and a type argument?类型参数和类型参数有什么区别? A type parameter, like a method parameter, occurs at eg a generic class/method declaration:类型参数,如方法参数,出现在例如泛型类/方法声明中:

class Foo<T extends SomeClass> {} // "T extends SomeClass" is a type parameter
class Bar<T> {} // "T" is a type parameter

This is analogous to method parameters:这类似于方法参数:

void foo(int i) {} // "int i" is a method parameter

A type argument, like a method argument, occurs where you use a generic class/method.类型参数,如方法参数,出现在您使用泛型类/方法的地方。 For example, in a field declaration:例如,在字段声明中:

Foo<? extends SomeClass> foo; // "? extends SomeClass" is a type argument
Bar<String> // "String" is a type argument

This is analogous to method arguments that you pass when you call a method:这类似于调用方法时传递的方法 arguments:

foo(1); // "1" is a method argument

So really, using T extends SomeClass where you should use ? extends SomeClass所以真的,使用T extends SomeClass你应该在哪里使用? extends SomeClass ? extends SomeClass makes no sense. ? extends SomeClass没有意义。 You are not declaring a new type variable here.您没有在这里声明一个新的类型变量。 You are merely constructing a generic type.您只是在构造一个泛型类型。

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

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