Вложение пяти условных операторов - PullRequest
4 голосов
/ 14 апреля 2011

Возможно ли вложить в 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" (или что-то подобное). Я спрашиваю здесь, потому что я не уверен, что этот отчет об ошибке будет содержать.


EDIT: Крис Л. воспроизвел это, см. Его ответ

Ответы [ 6 ]

1 голос
/ 11 апреля 2013

Я знаю, что это старый пост, но мой недавний опыт может пролить свет на эту тему для тех из вас, кто заинтересован. Это то, что нужно знать.

По сути, я "сломал" некоторый существующий код, реализовав 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
             : "?";
        }
1 голос
/ 14 апреля 2011

Я воспроизвел вашу ошибку (используя Sun JDK 1.6.0_24 на Mac).Я немного упростил ваш класс до:

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)
1 голос
/ 14 апреля 2011

Я не думаю, что есть ограничение, хотя оно синтаксически правильно.Я предполагаю, что компилятор java просто расширит свое дерево разбора, как для глубокого if / else if - nesting.

1 голос
/ 14 апреля 2011

Это прекрасно компилируется на 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, сколько пожелаете.

1 голос
/ 14 апреля 2011

Нет такого ограничения. Метод должен компилироваться до 64 КБ байтового кода.

Я хорошо скомпилировал твой пример. Есть ли причина, по которой у вас нет только одного поля?

РЕДАКТИРОВАТЬ: Добавлены сеттеры для проверки допустимых типов.

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;
    }
}
1 голос
/ 14 апреля 2011

Я могу только подтвердить, что это безошибочно компилируется для меня в 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...