13

Possible Duplicate:
Type-parameterized field of a generic class becomes invisible after upgrading to Java 7

public class Test{

    private String _canYouSeeMe = "yes";

    <T extends Test> void genericMethod(T hey){
        String s = hey._canYouSeeMe;
    }

    void method(Test hey){
        String s = hey._canYouSeeMe;
    }   
}

When building against JDK 1.6 this compiles just fine but against 1.7 there is a compiler error in genericMethod(): The field Test._canYouSeeMe is not visible

The error can be resolved by making _canYouSeeMe protected rather than private, but I'm just wondering what has changed from 1.6 to 1.7

Community
  • 1
  • 1
meta-meta
  • 926
  • 5
  • 11

2 Answers2

8

Subclasses (T) of a class (Test) never have access to the superclass' private fields. This was likely a bug in the Java 6 compiler that was fixed in Java 7.

Remember: T extends Test means that T is a subclass of Test. It does not mean that T's class is Test.class, which is the necessary condition for having private field & method access.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • this is partly true, but since the code accessing the private field is in the superclass itself, I would say it should have the access – Qnan Aug 01 '12 at 14:34
  • 2
    @Matt: I don't get it. If that were true, then why does casting `hey` to `Test` (which is entirely legitimate and doesn't even produce a warning) let's us access `_canYouSeeMe`? – Joachim Sauer Aug 01 '12 at 14:35
  • +1 A number of bugs in Java 6 were not fixed until Java 7 to avoid causing an incompatibility. – Peter Lawrey Aug 01 '12 at 14:36
  • Matt, so even though it's a static method (that uses generics), the compiler treats that as a generic class itself? – Martin Snyder Aug 01 '12 at 14:36
  • 2
    @JoachimSauer Because adding a field named `_canYouSeeMe` to the given subtype of `Test` would change the field access expression to refer to the new field. In this case, where the given type is a type variable, lowering the upper bound on the type variable could similarly change the meaning. Those bugs would creep up on us in utter silence. I for one welcome that particular door being firmly shut. – Ben Schulz Aug 01 '12 at 21:11
1

In reply to @Joachim - too long for a comment.

It is consistent with the fact that this would not compile:

void method(SubTest hey) {
    String s = hey._canYouSeeMe;
}

(where SubTest extends Test) whereas this would compile

void method(SubTest hey) {
    String s = ((Test) hey)._canYouSeeMe;
}
assylias
  • 321,522
  • 82
  • 660
  • 783