所以,我正在研究这个有一些静态常量的类:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Run Code Online (Sandbox Code Playgroud)
然后,我想要一种基于常量获取相关字符串的方法:
public static String lookup(int constant) {
switch (constant) {
case Foo.BAR: return "bar";
case Foo.BAZ: return "baz";
case Foo.BAM: return "bam";
default: return "unknown";
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我编译时,我constant expression required在每个3个案例标签上都会出错.
我知道编译器需要在编译时知道表达式来编译一个开关,但为什么不是Foo.BA_常量?
在开始之前,我知道这个问题有很多答案可以提出替代方法.我正在寻求这种特殊方法的帮助,以确定是否可行,如果不可能,可能会有类似的方法.
我有一个方法,它接受一个超类并根据传递的对象的类型调用一个方法.例如:
public void handle(Object o){
if (o instanceof A)
handleA((A)o);
else if (o instanceof B)
handleB((B)o);
else if (o instanceof C)
handleC((C)o);
else
handleUnknown(o);
Run Code Online (Sandbox Code Playgroud)
我不能修改子类型来覆盖一个handle()方法,正如这个答案所暗示的那样,因为我不拥有这些类.所以这个instanceof方法就是我所拥有的.
我想用一个switch声明代替if/else,只是因为它更整洁.我知道你只能打开基元和字符串,所以我要切换类名:
switch(o.getClass().getCanonicalName()){
case "my.package.A":
handleA((A)o);
break;
case "my.package.B":
handleB((B)o);
break;
case "my.package.C":
handleC((C)o);
break;
default:
handleUnknown(o);
break;
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是规范名称非常长(如12个子包),我不能调用ClassName.class.getCanonicalName()case语句,因为Java不允许这样做.所以我的下一个解决方案是Enum.这是我遇到问题的地方.
我希望我的代码看起来像这样:
public enum Classes {
A (A.getCanonicalName()),
B (B.getCanonicalName()),
C (C.getCanonicalName());
}
switch (o.getClass().getCanonicalName()){
case Classes.A:
handleA((A)o);
break;
case Classes.B:
handleB((B)o);
break;
case …Run Code Online (Sandbox Code Playgroud) 我正在研究注释处理器.此代码编译:
package sand;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.TypeElement;
@SupportedAnnotationTypes("sand.Foo")
public class FooProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
return false; // TODO
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我对字符串常量"sand.Foo"感到不满(在这种情况下不是太多,但对于将来会更多).
如果Foo重命名或移动到另一个包,此代码仍将编译,但它不起作用.
我想做的事情如下:
@SupportedAnnotationTypes(Foo.class)
Run Code Online (Sandbox Code Playgroud)
这样,如果Foo的名称发生变化,编译将失败,有人必须更正文件.
但这不起作用,因为a Class不是String.所以我尝试过:
@SupportedAnnotationTypes(Foo.class.getName())
Run Code Online (Sandbox Code Playgroud)
但编译器并不认为这是一个常量表达式,这在此上下文中是必需的,因此也不起作用.
在编译时有没有办法将类文字强制转换为它的名字?