相关疑难解决方法(0)

Java switch语句:需要常量表达式,但它是常量

所以,我正在研究这个有一些静态常量的类:

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_常量?

java compile-time-constant

159
推荐指数
7
解决办法
19万
查看次数

在java中切换类型

在开始之前,我知道这个问题有很多答案可以提出替代方法.我正在寻求这种特殊方法的帮助,以确定是否可行,如果不可能,可能会有类似的方法.

我有一个方法,它接受一个超类并根据传递的对象的类型调用一个方法.例如:

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)

java enums types instanceof switch-statement

27
推荐指数
3
解决办法
5万
查看次数

我可以将类的名称作为编译时常量获取而不用字符串文字对其进行硬编码吗?

我正在研究注释处理器.此代码编译:

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)

但编译器并不认为这是一个常量表达式,这在此上下文中是必需的,因此也不起作用.

在编译时有没有办法将类文字强制转换为它的名字?

java reflection constants compile-time-constant

15
推荐指数
2
解决办法
1605
查看次数