Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to restrict protected method access to only subclasses

Tags:

java

How can we restrict access of any protected method to only subclass in any package not to the class in the same package.

If any class that is not the subclass and in same package also it must throw exception like "Protected method."

Edit : Is there any way to check calling class name instance and then we can verify using instanceof .

like image 665
amicngh Avatar asked May 28 '12 12:05

amicngh


People also ask

Can protected methods be accessed by subclasses?

Yes, the protected method of a superclass can be overridden by a subclass. If the superclass method is protected, the subclass overridden method can have protected or public (but not default or private) which means the subclass overridden method can not have a weaker access specifier.

How can we prevent other classes from accessing a method?

When you declare a method in a Java class, you can allow or disallow other classes and object to call that method. You do this through the use of access specifiers. The Java language supports five distinct access levels for methods: private, private protected, protected, public, and, if left unspecified, "friendly".

How can we protect subclass to override the method of super class explain with example?

We can only use those access specifiers in subclasses that provide larger access than the access specifier of the superclass. For example, Suppose, a method myClass() in the superclass is declared protected . Then, the same method myClass() in the subclass can be either public or protected , but not private .

Can we access protected method outside the package?

The protected access modifier is accessible within the package. However, it can also accessible outside the package but through inheritance only. We can't assign protected to outer class and interface. If you make any constructor protected, you cannot create the instance of that class from outside the package.


2 Answers

It is not possible. You have a choice between protected modifier (subclasses + classes in the same package) and default modifier (classes in the same package). There is no third option.

Also you cannot easily enforce that at runtime as it is not simple to find the class name and package of the calling code. See: How do I find the caller of a method using stacktrace or reflection?

One option is using aspectj. It can even work at compile time to reject code trying to access protected method from the same package while not being a subclass (with a help of declare warning and declare error directives). You probably want to include some compile-time annotation like @SubclassesOnly. See: Compile-time architecture enforcement revisited: AspectJ, Maven and Eclipse and Compile-time checks with AspectJ.

like image 143
Tomasz Nurkiewicz Avatar answered Sep 21 '22 03:09

Tomasz Nurkiewicz


Easy: Remove all other classes from the package, leaving only your base class there.

That will mean the only classes that can access your class are from another package.

In the case that another library copies your package name, you could easily check the package of the caller and assert that it isn't the same as yours:

if (getClass().getPackage().equals(MyBaseClass.class.getPackage())
    throw new IllegalAccessError(); // or similar

FYI getClass() gives you the class of this, which would the subclass's class.

Edited:

To find the caller's class, use this code:

Class<?> callerClass = Class.forName(Thread.currentThread().getStackTrace()[2].getClassName());
like image 24
Bohemian Avatar answered Sep 22 '22 03:09

Bohemian