Java 嵌套五个条件运算符

Java 嵌套五个条件运算符,java,compiler-construction,Java,Compiler Construction,可以在Java中嵌套5个以上的“条件运算符”吗。我之所以这么问,是因为当我试图编译此代码时,似乎导致了编译器异常: public Object getValue() { return number != null ? number : string != null ? string : bool != null ? bool : date != n

可以在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编译器的一个局限性,或者我是否得出了错误的结论,如果其他人能够尝试重现这一点,那就太好了。如果有人感兴趣,我已经复制并发布了来自编译器的

请注意,这很可能是编译器中的错误,而不是我的代码,正如输出所说的“请在Java Developer Connect站点(或类似站点)提交错误”。我在这里发问是因为我不确定bug报告会包含什么内容


编辑:
Chris L复制了这一点,请参见他的

我只能确认,在eclipse 3.5和javac 1.6.0_24中,这一点对我来说都没有错误:

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

没有比这更低的限制了。方法必须编译为小于64KB的字节码

我很好地编译了你的例子。你有没有理由不只有一个字段

编辑:添加setter以检查有效类型

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;
    }
}
公共类持有者实现可序列化{
可序列化值;
公共无效设置值(数字值){
这个值=值;
}
公共void设置值(字符串值){
这个值=值;
}
公共void设置值(布尔值){
这个值=值;
}
公共无效设置值(日期值){
这个值=值;
}
公共无效设置值(L值){
这个值=值;
}
公共可序列化的getValue(){
返回值;
}
}

这在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;

    }
仔细检查
列表
的声明方式是否可以在方法内部访问



可能是java编译器中的错误。我建议您将java更新到最新和最好的版本(如果有的话)并复制。您可以安装任意多个不同版本的Java。

虽然语法正确,但我认为没有限制。我猜java编译器会像扩展深层if/else if嵌套一样扩展其解析树。

我重现了您的错误(在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;
    }
}

我知道这是一篇老文章,但我最近的经验可能会为你们中感兴趣的人提供一些关于这个主题的信息。这是需要注意的事情

基本上,我通过在我的另一个类中实现Comparable来“破坏”一些现有代码。下面是一个精简版本,它生成相同的“编译器中发生异常…”

如果嵌套条件中的表达式少于5个,或者USDollars类未实现可比较的表达式,则编译此代码


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

如果您想让人们确认,请提供一个完整的、可编译的示例来说明问题。至少,看到编译器的输出会很好。我在OSX上的JDK 1.6没有遇到此类错误。如果您遇到编译器错误,请提供您的环境(操作系统、编译器版本)和错误的详细信息。我们不能读心@Marcelo这里是编译器的输出:抱歉,这有点脱离上下文,作者对这个类的想法是,它是一个只能接受数字/string/bool/ect的容器,因此如果您将对象限制为存储某个有限集,那么这个类就是一个值的可序列化容器,使用所需类型的特定设置器,将值存储在单个公共对象成员变量中,这样就不需要复杂的getter。@Ben Page,不需要多个字段,只需要多个设置器即可。查看我的编辑。完全正确,我应该已经发现了,(尽管我的借口是代码不是我的;)谢谢@Peter&@AndyThanks,我将不得不看得更深一点,因为注释列表行是我能让我的程序编译的唯一方法,但它一定是其他原因造成的。在linus/sun java版本“1.6.0_20”(x32)上完美编译。很酷,谢谢Chris,你知道为什么将
ArrayList
更改为
List
Boolean
更改为
Object
可以解决这个问题吗?@Ben:我不知道,为什么。更奇怪的是,虽然用对象替换布尔值或日期有帮助,但用对象替换数字或字符串却没有帮助。

    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
             : "?";
        }