Java 通过反射获取导入类中声明的枚举常量
有类似于:Java 通过反射获取导入类中声明的枚举常量,java,reflection,Java,Reflection,有类似于: import com.example.test.classA; import com.example.test.classB; import com.example.test.classC; public class MyClass { ... Flavors p = Flavors.VANILLA; ... String flavorChoice = "Flavors.CHOCOLATE"; ... } 其中,Flavors是在其中一个导
import com.example.test.classA;
import com.example.test.classB;
import com.example.test.classC;
public class MyClass {
...
Flavors p = Flavors.VANILLA;
...
String flavorChoice = "Flavors.CHOCOLATE";
...
}
其中,Flavors
是在其中一个导入类中声明的enum
:
public enum Flavors { CHOCOLATE, VANILLA, LEMON };
如何使用反射从字符串选择?
不要假设我知道在哪个导入类中声明了Flavors
。
甚至不要假设可以从MyClass
中访问Flavors
澄清
字符串flavorChoices
应生成一个对象
,在上面的示例中,该对象可能是Flavors
类型。但它也可能引用其他枚举中的其他常量:
String flavorChoice = "ExtraFlavors.MENTA";
String flavorChoice = "ExoticFlavors.CHALK";
String flavorChoice = "AnyEmun.ANYCONSTANT";
直到运行时我才知道字符串内容是什么。我希望能够:
检查引用的枚举索引是否存在,是否可以从MyClass访问
获取引用的枚举常量并将其放入对象中
如果字符串重新定义如下:
String-flavorChoice=“巧克力”代码>
你甚至不需要思考。只需使用Flavors.valueOf(flavorChoice)
在你的情况下,你可以说:
String choice = "Flavors.CHOCOLATE";
String[] fragments = choice.split("\\.");
Enum.valueOf(Class.forName(fragments[0]), fragments[1]);
Class.forName(fragments[0])
将返回enum
的类,enum.valueOf()
返回enum
的元素
编辑:
如果在现实世界中,您的类属于包,您应该通过将split()
替换为其他内容来改进解析。如果您可以访问Flavors
类,如示例所示,valueOf
方法可能会很有用:
返回具有指定名称的此类型的枚举常量。字符串必须与用于在此类型中声明枚举常量的标识符完全匹配。(不允许使用无关的空白字符。)
因此:
如果您的问题是如何从香精中提取香草
,您可以尝试:
Flavor f = Flavors.valueOf("Flavors.VANILLA".replaceAll("^.*\\.", ""));
其中,*
是贪婪的量词
使用regex比使用split(\\”[1]
的优势在于,如果参数具有更高的限定条件,如classA.Flavors.VANILLA
或com.example.test.classA.Flavors.VANILLA
,则regex仍然可以工作。或者,您可以使用:
String[] parts = "Flavors.VANILLA".split("\\.");
String flavorPart = parts[parts.length - 1];
如果您不知道要引用哪一个特定的Flavors
类,那么这是如何工作的?也许,经过一些修改,可能会有用?但实际上,为什么您不知道类Flavors
是在哪里声明的呢?即使您通过反射获得它,如果您没有导入它,您也只能将其存储为对象(或枚举
)。@OliCharlesworth这就是为什么我在示例中使用Flavors p=Flavors.VANILLA
这一行,为了说明无需反射,我可以使用Flavors
,而不必确切知道它在哪里声明。为了简单起见,如果这有助于您制定答案,请假设系统中只声明了一个口味
。@WChargin实际上,我知道口味
在哪里声明。我事先不知道的是字符串flavorChoice
,它可以引用在该范围内可见的任何enum
。它甚至可以引用一些在那里无法访问的enum
,在这种情况下,我想调用一个RuntimeException
。更好的正则表达式-它也可以与SomeClass.Flavors.VANILLA一起使用。您也应该在拆分中使用它then@assylias我添加了split
部分,表明即使是最简单的正则表达式也可以使用,因为有些人不喜欢使用复杂的正则表达式。如果是这样的话,我真的认为最好做java.util.regex.Pattern.quote(“.”).split(identifierString)
,但也许那只是我…@wcharg,除了我在原始问题中对你的回复评论。如果我可以使用Flavors
,那就很好了,但是请注意我写的“甚至不要假设Flavors可以从MyClass中访问”。也许问题过于简单了,我会在这里补充一些说明。如果你能做香精p=Flavors.VANILLA
,那么你可以调用香精.valueOf
;我遗漏了什么吗?只要我需要为class.forName()提供类,这对我没有帮助。我需要一种方法来检查Flavors
是否是作用域中的已知类(注意,“作用域中的已知类”比检查当前对象子类要广泛得多,它可能是一个已知类,因为import
,或者因为层次结构中的某个父类声明了它)@ilamambo:AFAIK,没有关于反射机制可用的词汇范围的信息。所以,你所要求的可能是不可能的。
String[] parts = "Flavors.VANILLA".split("\\.");
String flavorPart = parts[parts.length - 1];