Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make E1 += E2 illegal while E1 = E1 + E2 is legal?

I've been reading Java Puzzlers by Bloch and Gafter and got to the puzzle 10 (Tweedledee). The essence of this puzzle is to

provide declarations for the variables x and i such that this is a legal statement:

x = x + i;

but this is not:

x += i;

The solution to this looks, according to the book, like this:

Object x = "Buy ";
String i = "Effective Java!";

The book claims that in the += operator the right-hand expression can be of any type only if the left-hand expression has type String. However, I tried to run this code, and it compiled and ran without any problems.

Then I dug into the Java Language Specification. Section 15.26.2 talks about two cases: when the left-hand expression is an array access expression and when it's not. If the left-hand operand expression is not an array access expression, then JLS doesn't say anything about the left-hand expression being a String. When it is, this part appllies:

If T is a reference type, then it must be String. Because class String is a final class, S must also be String. Therefore the run-time check that is sometimes required for the simple assignment operator is never required for a compound assignment operator.

❖ The saved value of the array component and the value of the right-hand operand are used to perform the binary operation (string concatenation) indicated by the compound assignment operator (which is necessarily +=). If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.

T here is the type of the left-hand operand as determined at compile-time, and S is the selected array component. So I thought that I would modify my code into this:

Object[] x = {new Object()};
String i = "Effective Java!";
x[0] += i;

But even this code compiles and runs without any problems even though new Object() is not even remotely a String.

Why is this happening? Does this mean that Java compiler deviates from the JLS? And is it still possible to somehow solve the original puzzle?

like image 863
Malcolm Avatar asked Jan 08 '13 15:01

Malcolm


People also ask

Can you adjust status from E2 visa?

The path from E2 visa to Green Card will require the visa holder to apply to a different immigration route, known as an 'immigrant' visa, either by making an application from outside the US or by applying to adjust your status from within the US.

How do I get an E1 E2 visa?

The US law states that to obtain an E1 / E2 visa as an essential employee, you must be hired as a manager, or supervisor. Or simply have special skills essential to the proper functioning and development of the company. In practice, this can cover most positions within a company.

What is E1 E2 status?

Whereas the USCIS rules state that the E1 visa is for nationals of a treaty country who require entry to in international trade on his or her own behalf, the E2 visa is for those who wish “to be admitted to the United States when investing a substantial amount of capital in a US business”.

What is difference between E1 and E2 visa?

The E1 visa is reserved for treaty traders and E2 visas is for treaty investors. To qualify for either E1 or E2, the applicant must be from a U.S. Department of State treaty country. Many countries on the list are classified as both E1 and E2, and thereby nationals may be eligible for either visa type.


2 Answers

I have the following and it show the given solution as the correct answer:

public class testIt
{
  public static void main(String args[])
  {
    new testIt();
  }

  public testIt()
  {
    Object x = "Buy";
    String i = "Effective Java!"

    x += i;

    x = x + i;
  }
}

when I compile this I get

testIt.java:  incompatible types
found:     java.lang.Object
required:  java.lang.String;

  x += i;
  ^
1 error
like image 36
jco.owens Avatar answered Sep 26 '22 04:09

jco.owens


Try with javac < 1.4.2, it will work there too.

This was a change between different release. The change for 1.4.2 (x += i; allowed before, not since):
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4642850

Which is correct, because the JLS 2. edition defined:

All compound assignment operators require both operands to be of primitive type, except for +=, which allows the right-hand operand to be of any type if the lefthand operand is of type String.

The change for 7 (x += i; not allowed before, allowed since):
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4741726

Which is correct since JLS 3. edition (see http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.26 the previous prerequisite is removed)


Just a small edit: I do not see any way to fix/solve the puzzle in Java 7.0_10

like image 78
tb- Avatar answered Sep 25 '22 04:09

tb-