Ambiguous call from static context in Java
Asked Answered
M

4

17

The main method tries to access var, but results in ambiguous call. Why? Instance variable var in Base1 isn't accessible (visible?) from static context anyway.

  class Base1 {
      int var;
  }

  interface Base2 {
      public static final int var = 0;
  }

  class Test extends Base1 implements Base2 { 
      public static void main(String args[]) {
          System.out.println("var:" + var); 
      }
  }
Mauricemauricio answered 7/7, 2014 at 14:9 Comment(8)
@Pablo, package does not matter. Just put the code snippet into one file and see the result.Probability
@Probability "Error - At least one public class is required in main file"Application
Well, make one of the classes public. Not this is the issue.Probability
The error message is self explanatory : reference to var is ambiguous, both variable var in Bof.Base1 and variable var in Base2 matchPapyrology
@AlexR, you're right, I deleted the answer. I suspect the answer is more complex, I think this can't be a compiler problem.Archdeaconry
seems like the compiler got outsmarted.. var of the interface should be considered because it is static..Salamone
I think that the compiler was playing safe, but the issue should be raised on the Test class as a whole, regardless of reference to var in the code. On non static context the issue is valid and nonetheless an indication that something was programmed wrong.Archdeaconry
In your test case initially compiler will tell you that an ambiguity is there, because the of the hierarchy at which the problem is. If you remove ambiguity than I am sure you will get the reference to non static member error.Diabolo
S
17

The JLS rule for field access ambiguity is

If the identifier names several accessible (§6.6) member fields in type T, then the field access is ambiguous and a compile-time error occurs.

And on the subject of accessibility

A member (class, interface, field, or method) of a reference type, or a constructor of a class type, is accessible only if the type is accessible and the member or constructor is declared to permit access:

It doesn't make a distinction about whether the instance field access would cause a compile error in a static context.

Note that you could have had

public static void main(String args[]) {
    Test test = new Test();
    System.out.println("var:" + test.var); 
}

You'd still have the ambiguity.

Soprano answered 7/7, 2014 at 14:30 Comment(0)
L
3

To make it unambiguous put the interface name as qualifying prefix:

class Test extends Base1 implements Base2 { 

      public static void main(String args[]) {
          System.out.println("var:" + Base2.var); 
      }
 }
Limpid answered 7/7, 2014 at 14:26 Comment(1)
Sometimes the compiler does not behave ans intelligent as we expect it to do. It might happen that the autor of the code meant the nonstatic field Base2.var In this case it is ambiguous (and wrong). (on the other hand, it is better to write unumbiguous code as the human brain needs some capacity to understand that. Just write code an idiot understands, than the compiler understands it as well :)Limpid
D
1

Inititally at step one compiler will look for variable var in the class which you extend and the interface you implement. Since it finds a variable at both places in step two, it shows ambiguity.

Diabolo answered 7/7, 2014 at 14:36 Comment(0)
A
1

The static and non static contexts do not rule on how variables are permitted to be accessed

The access modifiers are the ones which actually rule this...

change the access modifier for var in the Base1 to private and the ambiguity disappears, though this might not be the way you want it to shape up but access modfiers actually dictate the reference to instance variables rather than the static no static contexts.

class Base1 {
    private int var;
    //static int var=5;
}

interface Base2 {
    public static final int var = 0;
}

class ambiguousNonStaticCall extends Base1 implements Base2 { 
    public static void main(String args[]) {
        System.out.println("var:" + var); 
    }
}

The above code compiles fine.

Arachne answered 7/7, 2014 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.