2013-05-02 83 views
3
private static int testReturn(final boolean flag) { 
    return flag ? 1 : 2; 
} 

private static void testThrow1(final boolean flag) 
    throws IOException, SQLException { 

    if (flag) { 
     throw new IOException("IO"); 
    } else { 
     throw new SQLException("SQL"); 
    } 
} 

当我试图用?:操作去改变它,Java条件操作例外

private static void testThrow2(final boolean flag) 
    throws 
     //IOException, SQLException, // not even required 
     Exception {     // compiler wants this. 

    throw flag ? new IOException("IO") : new SQLException("SQL"); 
} 

它是正常的吗?

谢意

当我正准备介绍了Java 7种的功能,如多副渔获物和类型rethrowal我居然遇到了这个代码。有趣。谢谢大家这些好的答案。我学到了很多。

更新

Java 7中已经为特定类型重新引发了改进,对不对?

void throwIoOrSql() throws IOException, SQLException { 
} 

void rethrowIoAndSql() throws IOException, SQLException { 
    try { 
     throwIoOrSql(); 
    } catch (Exception e) { 
     throw e; // Ok with Java 7 
    } 
} 

这是有点愚蠢的编译器无法看到这些明显的情况。

throw flag ? new IOException("io") : new SQLException("sql"); // obvious, isn't it? 

回答

10

是的,不幸的是,编译器无法弄清楚你可以抛出这两个异常中的一个(并且语言规范不要求它)。

这里有一个三元运算符,返回一个Exception。这可以是SQLExceptionIOException,但唯一的常见超类型是Exception,所以这就是编译器将在此处看到的内容。

Java中没有“联合类型”。

同在这种情况下:

Object x = flag ? Integer.valueOf(1) : "a string"; 

这里,x也将是一个Object,因为没有其他的类型来表达Integer || String

0

这是完全正常的,?:运营商做同样的事情任何boolean值。

0

你的synatx是无效的。你可以做一些这样的事情。

Exception ex = true ? new IOException(): new Exception(); 
throw ex; 
-1

b ? new E1() : new E2() 

reference conditional expression。 Java语言规范有关如何确定此表达式的类型的规则。你表达的规则是这样的:

  • 否则,第二个和第三个操作数分别为类型S1S2。假设T1是应用装箱 转换为S1的结果,并且让T2成为将 装箱转换为S2的结果。条件表达式的类型是应用捕获转换(§5.1.10)至lub(T1, T2)的 结果。

lubleast upper bound,在这种情况下,它解析为Exception。由于Exception没有catch块,因此编译器会抱怨。


编译器抱怨

未处理的异常类型Exception

因为lubIOExceptionSQLException(即该三元表达的类型)是Exception。编译器本质上看,例如

private static void testThrow2(final boolean flag) throws IOException, SQLException { 
                // this won't compile 
    throw (Exception) new IOException("IO"); 
}