是否可以在Java中嵌套5个以上的“条件运算符”。我问,因为当我尝试编译此代码时,我似乎会导致编译器异常:
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
我已将其缩小到此代码,因为如果我注释掉最后一行,它似乎可以正常编译。
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
// list != null ? list :
null;
}
有没有人知道这是否是java编译器的限制,或者我跳到错误的结论,如果其他人可以尝试重现这一点,那将是很好的。如果有人感兴趣,我已复制并在此处Stack Trace发布编译器中的https://gist.github.com/919284。
请注意,很可能编译器中的错误不是我的代码,因为输出显示“请在Java Developer Connect站点上提交错误”(或类似内容)。我在这里问,因为我不确定那个bug报告会包含什么。
编辑: Chris L复制了这个,见他的answer
答案 0 :(得分:1)
我只能在eclipse 3.5和javac 1.6.0_u24中确认这个编译没有错误:
public class Test {
Object number=null, string=null, bool=null, date=null, list=null;
public Object getValue() {
return
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
}
答案 1 :(得分:1)
没有这么低的限制。方法必须编译为少于64KB的字节码。
我编写了你的例子。你有什么理由没有一个领域吗?
编辑:添加了设置器以检查有效类型。
public class Holder implements Serializable {
Serializable value;
public void setValue(Number value) {
this.value = value;
}
public void setValue(String value) {
this.value = value;
}
public void setValue(Boolean value) {
this.value = value;
}
public void setValue(Date value) {
this.value = value;
}
public <L extends List & Serializable> void setValue(L value) {
this.value = value;
}
public Serializable getValue() {
return value;
}
}
答案 2 :(得分:1)
这对于ideone编译很好:
public static void main (String[] args) throws java.lang.Exception
{
Object number = null;
Object string = null;
Object list = null;
Object bool = null;
Object date = null;
Object o =
number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
仔细检查list
是否以在方法内可访问的方式声明。
可能是您的java编译器中的错误。我建议你将你的java更新到最新的和最好的(如果有的话)并重现。您可以根据需要安装任意数量的Java版本。
答案 3 :(得分:1)
我认为语法上没有限制。我猜想java编译器会扩展其解析树,就像深度if / else if - nesting一样。
答案 4 :(得分:1)
我重现了你的错误(在Mac上使用Sun JDK 1.6.0_24)。我把你的课程简化为:
import java.util.ArrayList;
import java.util.Date;
public class Test3 {
private Number number;
private String string;
private Boolean bool; // Replace Boolean with Object, and it compiles!
private Date date;
private ArrayList<String> list; // Replace ArrayList with List, and it
// compiles!
public Object getValue() {
return number != null ? number :
string != null ? string :
bool != null ? bool :
date != null ? date :
list != null ? list :
null;
}
}
我的堆栈跟踪与您的堆栈跟踪基本相同。 (顺便说一下,它与GWT无关。)
An exception has occurred in the compiler (1.6.0_24). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError
at com.sun.tools.javac.jvm.Code$State.forceStackTop(Code.java:1688)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1679)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1678)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitConditional(Gen.java:1678)
at com.sun.tools.javac.tree.JCTree$JCConditional.accept(JCTree.java:1021)
at com.sun.tools.javac.jvm.Gen.genExpr(Gen.java:818)
at com.sun.tools.javac.jvm.Gen.visitReturn(Gen.java:1626)
at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1138)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:700)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:686)
at com.sun.tools.javac.jvm.Gen.genStats(Gen.java:737)
at com.sun.tools.javac.jvm.Gen.visitBlock(Gen.java:1013)
at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:739)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genStat(Gen.java:700)
at com.sun.tools.javac.jvm.Gen.genMethod(Gen.java:893)
at com.sun.tools.javac.jvm.Gen.visitMethodDef(Gen.java:866)
at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:639)
at com.sun.tools.javac.jvm.Gen.genDef(Gen.java:665)
at com.sun.tools.javac.jvm.Gen.genClass(Gen.java:2198)
at com.sun.tools.javac.main.JavaCompiler.genCode(JavaCompiler.java:617)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1289)
at com.sun.tools.javac.main.JavaCompiler.generate(JavaCompiler.java:1259)
at com.sun.tools.javac.main.JavaCompiler.compile2(JavaCompiler.java:765)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:730)
at com.sun.tools.javac.main.Main.compile(Main.java:353)
at com.sun.tools.javac.main.Main.compile(Main.java:279)
at com.sun.tools.javac.main.Main.compile(Main.java:270)
at com.sun.tools.javac.Main.compile(Main.java:69)
at com.sun.tools.javac.Main.main(Main.java:54)
答案 5 :(得分:1)
我知道这是一篇很老的帖子,但是我最近的经历可能会让那些感兴趣的人对这个问题有所了解。这是值得注意的事情。
基本上,我通过在其他一个类中实现Comparable来“破坏”一些现有代码。这是一个精简版本,生成相同的“编译器中发生异常......”
如果嵌套条件中的表达式少于5个,或者如果USDollars类没有实现Comparable,则此代码将编译。
public class TestHit
{
protected final String fSymbol;
protected final long fTime;
protected final USDollars fBasePrice;
public TestHit(String aSymbol, long aTime, int aBasePrice)
{
fSymbol = aSymbol;
fTime = aTime;
fBasePrice = new USDollars(aBasePrice);
}
public Object field(int aIndex)
{
return (aIndex == 0)? fSymbol
: (aIndex == 1)? fTime
: (aIndex == 2)? fBasePrice
: (aIndex == 3)? new Integer(4) // comment out this line and it compiles
: "?";
}
}
final class USDollars
implements Comparable<USDollars> // comment out this line and it compiles
{
private int cents;
public USDollars() { this(0); }
public USDollars(int cents) { this.cents = cents; }
public USDollars(int dollars, int cents) { this(cents + 100*dollars); }
public int cents() { return cents; }
// @Override
public int compareTo(USDollars other) { return this.cents - other.cents; }
}
顺便说一句,快速解决方法是修改代码如下(丑陋但是有效):
public Object field(int aIndex)
{
if (aIndex == 2)
return fBasePrice;
return (aIndex == 0)? fSymbol
: (aIndex == 1)? fTime
: (aIndex == 3)? new Integer(4) // comment out this line and it compiles
: "?";
}