web-dev-qa-db-ja.com

x + = yでコンパイルエラーが発生し、x = x + yでは発生しないように、xとyをどのように宣言しますか?

私はインタビューでこの質問に遭遇し、解決策を思い付くことができませんでした。 Javaで "+ ="演算子は何をしますか? に示すように、その逆も可能です。

質問は以下のようでした。

..... x = .....;
..... y = .....;

x += y; //compile error
x = x + y; //works properly
55
knshn

このコードを試してください

Object x = 1;
String y = "";

x += y; //compile error
x = x + y; //works properly

なぜこれが機能するのか完全にはわかりませんが、コンパイラは言います

演算子+ =は、引数タイプObject、Stringに対して未定義です。

2行目では、オブジェクトでtoStringが呼び出されていると仮定します。

編集:

+=演算子は一般的なオブジェクトでは無意味なので、これは理にかなっています。私の例では、intをObjectにキャストしましたが、それはxがObject型であることにのみ依存しています。

Object x = new Object();

ただし、xがObjectの場合にのみ機能するため、実際には、StringがObjectの直接のサブクラスであることが多いと思います。これはx + yでは失敗します:

Foo x = new Foo();

私が試した他のタイプのために。

55
Craigy

それは不可能。

X x = ...;
Y y = ...;

x += y;         //1
//equivalent to
x = (X) (x+y);  //2

x = x+y;        //3

x+yの型がZであると仮定します。#2ではZからXへのキャスト変換が必要です。 #3では、ZからXへの代入変換が必要です。「キャスト変換は代入変換よりも包括的です」(1)。したがって、#3が合法である限り、#2は合法であり、#1は合法です。

逆に、たとえば、#1は合法であるが、#3は違法である可能性があります。

    byte x = 0;
    int y  = 1;
    x+=y;     // ok, x=(byte)(x+y), cast int to byte is allowed.
    x = x+y;  // error, assign int to byte

この情報はまったく役に立ちません。これはJavaの欠陥であり、このような驚くべき違いを生み出します。

(1) http://Java.Sun.com/docs/books/jls/third_edition/html/conversions.html#5.5

3
irreputable
int  i = 5;
String s = "a";
System.out.println(i+=s);  //Error
System.out.println(i+s);   // No error

基本的に、任意のオブジェクト、または文字列以外のプリミティブと文字列の組み合わせに対して機能します。

どちらの会社だったのかな? :)

2
Bhushan

このことでコンパイルエラーが発生するとは限りません

あなたがこのようなsmoethingをしているなら:

class A{
public static void main(String args[]){
    String x = "10";
    String y = "s";
    x += y;
    System.out.println(x);
}
}

それはうまくいくでしょう

あなたがそうしても

class A{
public static void main(String args[]){
    int x = 10;
    float y = 11.5F;
    x += y;
    System.out.println(x);
}
}

正しく動作します。

しかし、xとyを取る場合、次のような2つの異なるタイプの変数を使用します。

class X{
 }
class A{
public static void main(String args[]){
    X x = new X();
    float y = 11.5F;
    x += y;
    System.out.println(x);
}
}

このような場合、コンパイルに失敗します。

*任意のint、floatなどをStringと連結することもできます。

1
gprathour