2

How could I create a method in a given class that can only be called internally by it, and its subclasses.

For example, the class Foo:

public class Foo{
    public Foo(){

    }
    ???? void bar(){

    }
}

and the class Baz, extending Foo:

public class Baz extends Foo{
    public Baz(){
        this.bar(); //valid
    }
}

but also, some other random class, Qux:

public class Qux{
private Baz baz = new Baz();
    public Qux(){
        baz.bar(); //invalid
    }
}

note that any of these classes could be in any package, so a simple 'protected' wont work.

if this isn't possible with a keyword or something similar, i'm open to suggestions on how to achieve similar behavior.

AlphaModder
  • 3,266
  • 2
  • 28
  • 44
  • You can keep this class in a separate package containing only this class..and make the method `protected` – Vishal K Jul 06 '13 at 09:12
  • would it be possible to use Thread.currentThread().getStackTrace()[1] or something to get the method caller and make sure its a valid source? – AlphaModder Jul 06 '13 at 09:20
  • @user1825860 if you want a runtime solution rather than a compile time solution then yes there are a few things that you could try. – selig Jul 06 '13 at 11:50
  • ok guys it turns out that my example was misunderstood and the whole problem could have been solved with protected because i didnt know about a feature of it. – AlphaModder Jul 09 '13 at 09:12

3 Answers3

1

There is no visibility level you can use. The levels are strictly nested in Java, and a level that would give access to subclasses but not the package would break that.

In Java 1.0 there was an access level "private protected" that did just this, and it was removed from later versions because it complicated the language and wasn't very useful: A subclass may be created by someone you don't trust, while code in the same package is controlled by you. Therefore it's more important to protect yourself from subclasses.

Joni
  • 108,737
  • 14
  • 143
  • 193
0

This is not really possible with an access modifier. As you have only two choices between protected modifier (subclasses + classes in the same package) and default modifier (classes in the same package).

The only way you can achieve this by removing all non-child classes to other packages with protected/default access specifier.

Juned Ahsan
  • 67,789
  • 12
  • 98
  • 136
0

public is the only keyword that allow to call a method from non-extending class in a different package. So if you still want to hide the method from pulic view and put your class anywhere, you will have to invoke the method via reflection (which is dirty).

PomPom
  • 1,468
  • 11
  • 20