2016-07-08 11 views
2

プロジェクトをJava 1.7から1.8にアップグレードしています。コードをコンパイルするとcompile errorとしてintはキャストできません。です。intをJavaで長時間キャストできません。

ここにプリミティブlongを返す式を示します。

public Long getOrganizationIdByUser(String userId){ 

     Query query = getSession().getNamedQuery("getOrganizationIdByUser"); 
     query.setString("id", userId!=null?_userId.toLowerCase():null); 

     List<Long> returnList = query.list(); 
     return returnList!=null&&returnList.size()>0?returnList.get(0):0; 

    } 

これは、Javaの基本的な概念であり、また、それは、Java 1.7で正常に動作しますので、は、Java 1.8でlongにキャストすることはできませんなぜ私が混乱してきました。

エラー

error: incompatible types: bad type in conditional expression 
    [javac]   return returnList!=null&&returnList.size()>0?returnList.get(0):0; 
    [javac]                  
    [javac]  int cannot be converted to Long 
+3

「returnList」とは何ですか? (私はJava 1.8でこれを再現できません) –

+4

オペランドの型に応じて、 '?:'演算子の戻り値の型に固有の規則があります。http://docs.oracle.com/javase/specs/ jls/se8/html/jls-15.html#jls-15.25。これに基づいて、ボクシングとアンボクシングはバックグラウンドで行われます。そして、私は、結果を代入する変数の型として 'Long'を使用したときにそれを再現できますが、' long'が機能します。ですから、問題を示すコードが同じになるように[mcve]を提供してください。 –

+5

[Java 8 - 整数を長いコンパイルの問題に変換する]の可能な複製(http://stackoverflow.com/questions/27105299/java-8-converting-an-integer-to-a-long-compilation-issue) –

答えて

1

末尾に 'L' を追加してみてください:

returnList != null && returnList.size()>0 ? returnList.get(0) : 0L; 

OR 'returnList.get(0)'、int型を返すしよう:

returnList != null && returnList.size()>0 ? (long)returnList.get(0) : 0L; 
+3

ええ、それはそのように動作しますが、なぜ以前の式がJava 1.7のように機能しないのですか? – Shashika

+0

コーディング中にもっと正確になるかもしれませんか? :) –

+1

@JérèmLeBlond質問があります:どのようなJava言語のルールがJava 8でもうコンパイルされないように変更されましたか?オラクルは常に後方互換性に非常に注意を払っており、まったく正当な理由なくルールを変更することはありません。 – Jesper

4

数値条件式には "Binary Numeric Promotion"が含まれているため、次のコードをコンパイルすることができます。

Long long1 = null; 
Integer int1 = null; 
Long long2 = true? long1: int1; 

両方の選択肢が数値型を持っているので、数値昇格は、第intオペランドに拡大変換を適用し、その後、値をVHS版れる、適用ので、条件式longの結果型を有します。その後、ボクシングはLongになります。

したがって、上記のコードではなく、直接アンボクシングとボクシングステップによるlong2からlong1で見つかったオブジェクトを割り当てるのNullPointerExceptionを投げるの直感的挙動を有します。


同じLongintとの組み合わせに適用され、一方のオペランドの結果は、メソッド呼び出しがある場合にも、例えば

static Long test() { 
    return Math.random()<0.5? test(): 0; 
} 

は問題なくコンパイルできます。違いは何ですか?例えば

public Long test() { 
    List<Long> returnList = new ArrayList<Long>(); 
    return returnList!=null&&!returnList.isEmpty()? returnList.get(0): 0; 
} 

にメソッド呼び出しは、ジェネリッククラスのインスタンスで構成されています。

The specificationは言う:

...

  • 第二と第三のオペランド式の両方が数値式ている場合は、条件式は数値条件式です。

    • スタンドアロン形式(§15の式:条件を分類するため
      は、以下の式は、数値式です。2)を数値型に変換可能な型に変換する(§4.2、§5.1.8)。

    • 括弧内の数値式(15.8.5)。

    • 数値型に変換可能なクラスのクラスインスタンス作成式(15.9)。

    • 選択された最も具体的なメソッド(15.12.2.5)の戻り値の型が数値型に変換可能なメソッド呼び出し式(15.12)。

    • 数値条件式

これが原因の反対である「スタンドアロン型」表現の導入に、Java(登録商標)7に比較して変更されていることに注意してくださいターゲットのタイピングの対象となる「ポリ発現」。

メソッド呼び出しは、スタンドアローン式またはポリ式であるかどうかを確認するために、我々はJLS §15.12を参照する必要があります。次のすべてに該当する場合

メソッド呼出し式は、ポリ式です:

  • 呼び出しは、割り当てコンテキストまたは呼び出しコンテキスト(5.2、§5.3)に現れます。

  • 呼び出しが修飾されている場合(つまり、最初のMethodInvocationを除く任意の形式のMethodInvocation)、呼び出しは識別子の左側にTypeArgumentsを削除します。

  • 次のサブセクションで決定されるように、呼び出されるメソッドは汎用(§8.4.4)であり、メソッドの型パラメータの少なくとも1つを記述する戻り型を持ちます。

それ以外の場合、メソッド呼び出し式はスタンドアロン式です。

ここでは、最後の箇条書きは適用されません。このメソッドはジェネリッククラスのメンバですが、ではなくではないので、型パラメータを宣言しないため、戻り値の型はメソッドの型パラメータを参照しません。

つまり、このメソッド呼び出しは数値の戻り値型を持つスタンドアロン式です。したがって、条件式は数値条件式であり、他の例と同様に、2進数値昇格の対象となります。


最新のすべてのJava 9実装では、Java 6およびJava 7の実装と同様に、このコードをコンパイルすることに注意してください。

関連する問題