如何声明x和y使x+=y产生编译错误而x=x+y没有?

时间:2021-06-15 01:16:02

I ran into this question in an interview and couldn't come up with a solution. I know the vice versa can be done as shown in What does the "+=" operator do in Java?

我在一次面试中遇到了这个问题,无法找到解决方案。我知道反之亦然,正如“+=”操作符在Java中所做的那样。

So the question was like below.

问题是这样的。

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

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

4 个解决方案

#1


55  

Try this code

试试这个代码

Object x = 1;
String y = "";

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

not entirely sure why this works, but the compiler says

不完全确定为什么会这样,但是编译器说

The operator += is undefined for the argument type(s) Object, String

对于参数类型(s)对象、字符串,操作符+=是未定义的。

and I assume that for the second line, toString is called on the Object.

我假设对于第二行,对对象调用toString。

EDIT:

编辑:

It makes sense as the += operator is meaningless on a general Object. In my example I cast an int to an Object, but it only depends on x being of type Object:

它是有意义的,因为+=运算符在一般对象上是没有意义的。在我的例子中,我将int类型转换为对象,但它只依赖于类型对象的x:

Object x = new Object();

It only works if x is Object though, so I actually think it is more that String is a direct subclass of Object. This will fail for x + y:

只有当x是对象时它才有效,所以我认为字符串是对象的直接子类。x + y会失败:

Foo x = new Foo();

for other types that I have tried.

对于我尝试过的其他类型。

#2


3  

It is not possible.

这是不可能的。

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

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

x = x+y;        //3

Suppose the type of x+y is Z. #2 requires a casting conversion from Z to X; #3 requires an assignment conversion from Z to X. "casting conversions are more inclusive than assignment conversions"(1). Therefore, as long as #3 is legal, #2 is legal, and #1 is legal.

假设x+y的类型是Z。#2要求从Z到x的转换;#3需要从Z到X的赋值转换。“施法转换比赋值转换更具包容性”(1)。因此,只要#3是合法的,#2是合法的,#1是合法的。

On the reverse side, it is possible that #1 is legal, but #3 is illegal, for example

从反面来看,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

This information is not useful whatsoever; it is a flaw of Java making such surprising differences.

这些信息毫无用处;Java的缺陷造成了如此惊人的差异。

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

(1)http://java.sun.com/docs/books/jls/third_edition/html/conversions.html 5.5

#3


2  

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

Basically, works for Any object or any non-string primitive and String combination.

基本上,适用于任何对象或任何非字符串原语和字符串组合。

I wonder which company it was? :)

不知道是哪家公司?:)

#4


1  

This thing will not always give you compilation error

这个东西不会总是给你编译错误

If you are doing smoething like this :

如果你正在做这样的事:

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

It will work fine

它将正常工作

even if you do

即使你

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

it will work properly.

它将正常工作。

But if you take x and y two different type of variables like :

但是如果你取x和y两个不同类型的变量,比如

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

In such cases it will fail to compile.

在这种情况下,它将无法编译。

*Even you can concatinate any int, float etc with String.

*甚至你也可以用字符串合并任何int、float等。

#1


55  

Try this code

试试这个代码

Object x = 1;
String y = "";

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

not entirely sure why this works, but the compiler says

不完全确定为什么会这样,但是编译器说

The operator += is undefined for the argument type(s) Object, String

对于参数类型(s)对象、字符串,操作符+=是未定义的。

and I assume that for the second line, toString is called on the Object.

我假设对于第二行,对对象调用toString。

EDIT:

编辑:

It makes sense as the += operator is meaningless on a general Object. In my example I cast an int to an Object, but it only depends on x being of type Object:

它是有意义的,因为+=运算符在一般对象上是没有意义的。在我的例子中,我将int类型转换为对象,但它只依赖于类型对象的x:

Object x = new Object();

It only works if x is Object though, so I actually think it is more that String is a direct subclass of Object. This will fail for x + y:

只有当x是对象时它才有效,所以我认为字符串是对象的直接子类。x + y会失败:

Foo x = new Foo();

for other types that I have tried.

对于我尝试过的其他类型。

#2


3  

It is not possible.

这是不可能的。

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

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

x = x+y;        //3

Suppose the type of x+y is Z. #2 requires a casting conversion from Z to X; #3 requires an assignment conversion from Z to X. "casting conversions are more inclusive than assignment conversions"(1). Therefore, as long as #3 is legal, #2 is legal, and #1 is legal.

假设x+y的类型是Z。#2要求从Z到x的转换;#3需要从Z到X的赋值转换。“施法转换比赋值转换更具包容性”(1)。因此,只要#3是合法的,#2是合法的,#1是合法的。

On the reverse side, it is possible that #1 is legal, but #3 is illegal, for example

从反面来看,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

This information is not useful whatsoever; it is a flaw of Java making such surprising differences.

这些信息毫无用处;Java的缺陷造成了如此惊人的差异。

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

(1)http://java.sun.com/docs/books/jls/third_edition/html/conversions.html 5.5

#3


2  

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

Basically, works for Any object or any non-string primitive and String combination.

基本上,适用于任何对象或任何非字符串原语和字符串组合。

I wonder which company it was? :)

不知道是哪家公司?:)

#4


1  

This thing will not always give you compilation error

这个东西不会总是给你编译错误

If you are doing smoething like this :

如果你正在做这样的事:

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

It will work fine

它将正常工作

even if you do

即使你

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

it will work properly.

它将正常工作。

But if you take x and y two different type of variables like :

但是如果你取x和y两个不同类型的变量,比如

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

In such cases it will fail to compile.

在这种情况下,它将无法编译。

*Even you can concatinate any int, float etc with String.

*甚至你也可以用字符串合并任何int、float等。