Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 通过反射获取导入类中声明的枚举常量_Java_Reflection - Fatal编程技术网

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];