indexed access: 10 ways to fix 'harmfull' issue

Ruslan Shevchenko rssh at gradsoft.com.ua
Thu Jun 25 17:39:47 PDT 2009


> Ruslan Shevchenko wrote:
>> 3. Change semantics in assigment in that way, that indexed assigment
>> also
>> return value of right part, casted
>>  to type of left part.
>>  looks strange from some point of view : minor:
>> // (x[i]=b)==x[i]  can be not always true, becouse we return right part
>> instead left.
>>
>> Map<Integer,Integer> x = new HashMap<Integer,Integer>();
>> if ((x[1]=128)==x[1]) {
>>  System.err.println("eq");
>> } else {
>>  System.err.println("neq");
>> }
>>  will print neq.
>>
>> int[] x = new int[1];
>> if ((x[1]=128)==x[1]) {
>>  System.err.println("eq");
>> } else {
>>  System.err.println("neq");
>> }
>>  will print eq.
>>
>>  backward compability: yes (if will not change rules for arrays and
>> variables)
>>  extra  overhead:      no
>>  limited functionality: no
>>
>> //Comment: some existing statements of JLS will be changed, but for
>> arrays
>> and plain variables
>> // we have choise:  left the same as previous,
>>
>
> As far as I understand it, your upper example will also return eq. 128
> will be autoboxed to Integer, then duplicated on stack, then put into
> x[1] and then compared to value got from x[1]. Additionally, don't use

Exists two ways for compiler to return right part.
1: do autoboxing, than duplicate received integer on stack, than call method.
2: call put (do autoboxing if needed), than return right part (do
autoboxing again if needed).

In case of (1) it will print eq.  In case of (2) - neq.

I assumed scenario 2.

// let's rewrite one in today-s java.

 public static void main(String[] args)
 {
   Map<Integer,Integer> map = new HashMap<Integer,Integer>();
   // x[1]=128
   Integer tmp=128;
   map.put(1,128);
   if (map.get(1)==tmp) {
       System.err.println("eq");
   } else {
       System.err.println("neq");
   }
 }


But yes, we can force scenario 1,

require in specification of assignment
1.  if indexed setter call require autoboxing or integer type conversions -
  do one first and store in temporary variable
2.  call setter with stored temporary variable (let call one boxedRight)
3.  return boxedRight

Then yes, scenario will be you:

 public static void main(String[] args)
 {
   Map<Integer,Integer> map = new HashMap<Integer,Integer>();
   Integer tmp=128;
   map.put(1,tmp);
   if (map.get(1)==tmp) {
       System.err.println("eq");
   } else {
       System.err.println("neq");
   }
 }


Wow - this is clear solution, which I miss !






More information about the coin-dev mailing list