2016-11-10 3 views
2

Javaで三項演算子によってメソッドの引数を渡す:私はこのコードを実行するとコード

public class Foo { 

    static void test(String s){ 
     System.out.println("String called"); 
    } 

    static void test(int s){ 
     System.out.println("int called"); 
    } 

    public static void main(String[] args) throws Exception { 

     test(5>8? 5:8);   // Line 1 
     test(5>8? "he":"ha"); // Line 2 

     test(5>8? 5:"ha");  // Line 3 

     System.out.println(5<8? 5:"ha"); //Line 4 
    } 
} 

私は三項演算子に似たタイプを使用してLine 3

Foo.java:24: error: no suitable method found for test(INT#1) 
       test(5>8? 5:"ha");    // Line 3 
       ^

で次のエラーを取得することはありませんエラーを返す。しかし、異なるタイプを使用すると、メソッド呼び出し​​にのみエラーが発生しますが、私は別のオーバーロードされたメソッドstatic void test(Object s){}、その後、//Line 3コンパイルを追加すると、それはコールSystem.out.println(5<8? 5:"ha");

のために動作します。

誰でもこのシナリオを説明できますか?

答えて

4

Javaのすべての式には型があります。 5 > 8 ? 5 : "ha"のような条件式の型を見つける方法を教えてくれるthe conditional operatorの節には、Java言語仕様にいくつかの複雑な規則があります。しかし、簡単に言えば、第二引数と第三引数の両方がメンバーである最も具体的な型を常に得ることができます。 5 > 8 ? 5 : 8について

  • 58両方がintあるので、この式全体はint型を持ちます。
  • 5 > 8 ? "he" : "ha"の場合、"he""ha"Stringです。したがって、この全体の表現はタイプStringです。
  • 5 > 8 ? 5 : "ha"の場合、5"ha"の両方に適合する最も特殊なタイプはObjectです。だからこの全体表現はタイプObjectです。

は今、あなたはintを受け入れ、Stringを受け入れるtestのバージョン、表現test (5 > 8 ? 5 : 8)test (5 > 8 ? "he" : "ha")両方のコンパイルを持っているので。

を受け入れるtestのバージョンがない場合、test (5 > 8 ? 5 : "ha")はコンパイルできません。

これはあまり単純化されていません。ルールは私が記述したよりもはるかに複雑ですが、これは主に、nullオペランド、自動ボクシング、自動アンボックを含むさまざまなケースを考慮しているためです。

+0

よくお答えください! –

+0

ここでは、三項演算子の戻り値の型を決定する方法を理解しています。あなたの説明に基づいて、 'System.out.println()'メソッドが、Objectをパラメータとして受け取り、PrintStreamに 'public void println(Object x)'メソッドがあるオーバーロードされたメソッドがあるかどうか疑問に思った。あなたの答えにこの点を加えることができれば、それは他の人には役に立ちます。 –

+0

私はそれがまったく別の問題だと感じます。また、ほとんどのJavaプログラマは、好きなオブジェクトを 'System.out.println'に渡すことができることを知っています。 –

0

式が評価される前にメソッドを呼び出しています。このメソッドにはtest(Object o)のオーバーロードがないため、動作しません。

左側の式を解決してからメソッドを呼び出します。

5>8?test(5):test("ha") 
0

あなたは(ここで)

test(5>8? 5:8);
メソッド関数を呼び出している場合は、括弧内の全部がパラメータとして考えられているので、パラメータを送信することを意図し、そのように対処するために何の適切な/適切な方法はありませんあなたが文の1つでintとStringを評価しているときに、種類の呼び出し(そのパラメータはObjectでなければなりません)。したがって、3項演算子はそこでは実行できません。

したがって、あなたがこの

(5 > 8) ? test(param1): test(param2); 


またはパラメータとしてオブジェクトと、そのテストメソッド内で物事を評価受け入れる別のテストメソッドを作成するようなコードを使用することができます。このように

void test(Object o){ 
    //manipulate things here 
}