【问题标题】:In Java, can I use the conditional expression to "choose" reference types?在 Java 中,我可以使用条件表达式来“选择”引用类型吗?
【发布时间】:2011-01-29 18:13:36
【问题描述】:

我可以使用条件表达式来“选择”一个引用类型,如下所示?

??? = isTrue() ? Integer : Double;

我可以在“???”中放置一些东西来使代码 sn-p 可编译吗?

编辑:当我写 Integer 和 Double 时,我并不是指 Integer 或 Double 的实例。我的意思是引用类型 Integer 和 Double。

【问题讨论】:

  • 我不想做任何事情。我只是想知道是否可能。

标签: java conditional-operator


【解决方案1】:

我认为您正在尝试使用三元布尔运算符来选择变量的引用类型。

这在 Java 中是不可能的,因为 Java 是 静态 类型的 - 这意味着每种类型在编译时都已明确定义。您的表达式想要运行一个方法并根据其输出确定在编译时不可能的引用类型。

【讨论】:

    【解决方案2】:

    不,因为这在语法上不是有效的 Java。如果将 Integer 替换为 Integer.class 并将 Double 替换为 Double.class,它将正常工作。但是,我认为这不是您想要的。

    在那种情况下,???应该是

    类变量

    【讨论】:

    • 我想知道是谁投了这个完全错误的答案。当然它在语法上不是有效的 java,但问题显然不是这样。
    • 理解我问题的人。我怀疑这是不可能的,但我想得到保证。谢谢。
    • @John Assymptoth 那时我的立场是正确的。很抱歉,我什至没有想到这可能是个问题。
    【解决方案3】:

    您可以选择实现,但不能使用实现的任何专长;在您的示例中,您可以这样做

    Number n = isTrue() ? 1 : 1.0;
    

    这将被自动装箱为下面的正确数据类型,但由于超类是数字,你真的无法用它做很多事情。

    编辑:

    由于上面的实际示例是 Java 中的一个已知错误,因此还有一个行为符合预期:

    CharSequence cs = isTrue() ? "I'm a String"
                               : new StringBuilder().append("I'm a StringBuilder");
    
    System.out.println(cs+" "+cs.getClass());
    // prints out
    // I'm a String class java.lang.String
    

    【讨论】:

    • 你试过了吗?这行不通。无论isTrue() 返回什么,您的代码都将始终返回Double。这是一个已知的 Java 陷阱。
    • @Jesper:我在这里解释一般概念(通用的超类/接口如何在条件句中用作基类型,以允许将不同的子类作为实际类型),不是特定的用例——诚然,它确实被打破了。 JDK 本身并没有包含太多其他有用的示例...我将在另一个没有错误的示例中进行编辑。
    【解决方案4】:

    你可以做类似的事情,但你必须将 Integer 和 Double 作为字符串传递给另一个参数,也许是一个可以实例化你正在寻找的类型变量的构造函数。正如你所看到的,这个解决方案需要很多创造力,所以我猜你的问题的更简短和更正确的答案并不是真的。

    【讨论】:

      【解决方案5】:

      您可以使用不同的类型,但您必须将结果存储在两者的超类型中。所以快速回答是否定的,你不能这样选择引用类型。

      你能得到的最接近的是将它们存储在最接近的可用超类型中(在本例中为数字):

      Number n = functionReturningBoolean() ? 1.0 : 1;
      

      ...然后,如果您真的想访问特定于单一类型的内容,请检查并强制转换。虽然这很讨厌,但我想不出我会在实践中使用它的情况(尽管这不是挖掘,纯粹的学术问题与实际问题一样有效!)

      【讨论】:

      • 这行不通,n 将永远是Double,无论布尔表达式的结果是什么。试试看!
      【解决方案6】:

      如果你只是想选择一个类型,而不是一个实例,你可以这样做:

      类结果 = isTrue() ?整数类 |双.class;

      【讨论】:

      • 你可以声明Class<? extends Number> result 而不仅仅是Class result
      【解决方案7】:

      编辑:我原来的答案是错误的,正如 Jesper 所指出的那样......感谢 Jesper,我还有另一个理由劝阻人们不要使用三元运算符,因为以下 if/else行为体现了我最初追求的行为:

       Number n;
          if (isTrue()) { n = Double.valueOf(1.0); }
          else {n = Integer.valueOf(1);}
          System.out.println(n.getClass().getName()) //prints java.lang.Integer if isTrue returns false
      

      原答案:

      您需要分配给 Double 或 Integer 的超类型才能使其工作。数字应该可以解决问题。

      Number n = isTrue() ? whateverYouDoToReturnInteger() :  whateverYouDoToReturnDouble();
      

      当然,您将在这里丢失确切的子类型,但它至少会编译您想要的。

      【讨论】:

      • @Jesper,到处投票给你的 cmets。感谢您指出这一点。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 2010-09-29
      • 1970-01-01
      • 2011-04-21
      相关资源
      最近更新 更多