2

The class ExtendedDismaxQParser has a static member class Clause:

public class ExtendedDismaxQParser {
    protected static Class Clause {
        protected String foo, bar;
    }
    public Clause getAClause {
        Clause c;
        // misc code that isn't important
        return c;
    }
}

I then extended this class in a different package:

public class SpecialDismaxQParser extends ExtendedDismaxQParser {
    public void whatever() {
        Clause c = super.getAClause();
        boolean baz = c.foo.equals("foobar"); // <-- This doesn't compile
    }
}

It looks like you can't access the foo member variable, despite the fact that the class Clause is protected, and the member variable foo is also protected.

I just want to be able to check something about the member variable foo of the protected static class Clause. How can I do this (preferably without reflection)?

I would greatly prefer to not have to modify the parent class because it is a part of a library.

zelinka
  • 3,271
  • 6
  • 29
  • 42
  • This is because Clause is not the class being extended. Here's a good reference table: http://stackoverflow.com/a/33627846/276052 – aioobe Mar 18 '16 at 20:06
  • Take a look at http://stackoverflow.com/questions/14534421/java-extending-inner-classes . – bradimus Mar 18 '16 at 20:11
  • I had wrote an answer, but my internet went off and it appears to have been deleted. Basically, make the fields `public`, as they are currently only visible to subclasses of the inner class (and elsewhere in the same package). – bcsb1001 Mar 18 '16 at 20:11
  • Most of those analyses describe classes, not inner classes. – zelinka Mar 18 '16 at 20:15
  • @zelinka But the rule still applies. As I have said, `protected` members of inner classes are only accessible to subclasses of the inner class (and elsewhere in the package). – bcsb1001 Mar 18 '16 at 20:23

3 Answers3

1

aioobe's comment is correct.

Sharing a superclass with the outer class isn't enough to get access to protected members of the static inner class.

The caller's class doesn't extend Clause, and is in a different package. For protected to be relevant you'd have to access foo from within a subclass of Clause, or access it from a class in the same package as ExtendedDismaxQParser.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
0

As already been said in the comments and very well explained in the answer by @Nathan Hughes, you can not access the protected field in Clauseas it is not the class being extended.

The only way to access this field is unfortunately through reflection

public class SpecialDismaxQParser extends ExtendedDismaxQParser {
    public void whatever() {
        try {
            Field fooField = Clause.class.getDeclaredField("foo");
            fooField.setAccessible(true);
            Clause c = super.getAClause();
            boolean baz = fooField.get(c).equals("foobar");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
gustf
  • 1,959
  • 13
  • 20
-3

Protected access modifiers allow variables and methods to be accessed within the package only. You have create your class inside the package of your Clause class.

Reflection will not do you any good here.

rahsan
  • 170
  • 9
  • Are you not mixing it up with package-private access? – aioobe Mar 18 '16 at 20:09
  • Just google Java access modifiers before down voting – rahsan Mar 18 '16 at 20:10
  • @rahsan Just Google Java access modifiers before posting an incorrect answer. `protected` access also applies to subclasses. – bcsb1001 Mar 18 '16 at 20:13
  • `protected` members are visible to a subclass [regardless of the package](https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html). – bradimus Mar 18 '16 at 20:14
  • @bradimus Any class in the same package may also access `protected` members. – bcsb1001 Mar 18 '16 at 20:16
  • 1
    @bcsb1001 My comment does not suggest otherwise. My comment does, however, point out an error in the answer that claims "accessed within the package only." – bradimus Mar 18 '16 at 20:19
  • @everybody downvoting he is not extending Clause, but ExtendedDismaxParser, he either needs to extend Clause or put his class in the same package as Clause – rahsan Mar 18 '16 at 20:22
  • here is a link in case you don't know how to extend inner classes : http://stackoverflow.com/questions/9458123/inner-class-extending – rahsan Mar 18 '16 at 20:31