Decreasing the visibility of a static method

I know that a child cannot reduce the visibility of a non-static method, and I understand why this is so.

I read, however, that "the static method can be hidden by re-declaring it." However, I do not understand how this could be achieved in Java.

Is it really possible? If so, how to do it (sample code) and why was it introduced (this, apparently, contradicts the principle without reducing the visibility of the interface)?

+1
source share
4 answers

Short answer: no, this is not possible. You have mixed up some terminology. Hiding has nothing to do with accessibility (which you really ask, not about visibility, which is related to scope and shading and is discussed in Chapter 6, Java Language Specification (JLS ).

Now for a longer answer. The term override applies to instance methods, while the term "hiding" applies to class methods ( static ). From the Java Tutorial section . Override and Hide Methods :

The difference between hiding a static method and overriding an instance method has important consequences:

  • The version of the overridden instance method that is being called is one in the subclass.
  • The version of the hidden static method that is being called depends on whether it is called from a superclass or subclass.

Some of the other answers here give incorrect examples about hiding a method, so back to JLS, this time §8.4.8

Methods are overridden or hiding signature signatures.

That is, in order to override or hide the method in the parent class, the subclass must define a method with the same signature - basically the same number and type of arguments (although generalizing and deleting types makes the rules a little more complicated than that). There are also rules about return types and throws clauses, but they are not relevant to this issue.

Note that you can define a method in a subclass with the same name as the method in the parent class (or in the implemented interface), but with a different number or type of arguments. In this case, you overload the method name and neither override nor hide anything; a subclass method is a new method that is virtually independent of the inherited method (s). (There is interaction when the compiler must map methods to method calls, but more on that.)

Now to your question: the terms “accessibility and concealment” (as well as visibility) are independent concepts in Java. There is, as you put it, a “principle” that there is simply no way for a subclass to reduce the availability of an inherited method. This applies regardless of whether you override the instance method or hide the class method. From JLS §8.4.8.3 :

The access modifier ( §6.6 ) of the override or hide method must provide at least the same access as the overridden or hidden method, because as follows:

  • If the overridden or hidden method is public , then the override or hide method must be public ; otherwise, a compile-time error occurs.

  • If the overridden or hidden method is protected , then the override or hide method must be protected or public ; otherwise, a compile-time error occurs.

  • If an overridden or hidden method has default access (package), then the override or hide method should not be private ; otherwise, a compile-time error occurs.

Thus, the fact that the static method can be hidden has nothing to do with changing the availability of the method.

+3
source

Based on valuable valuable comments, it seems that the author of the application meant hiding the method, overloading it with a method that has the same declaration.

Quote link :

We can declare static methods with the same signature in a subclass, but this is not considered overriding, since there will be no runtime polymorphism. (...) If the derived class defines a static method with the same signature as the static method in the base class, the method in the derived class hides the method in the base class.

Thus, defining a method in a child class that has the same declaration effectively hides the original method in the child. However, as in the case of fields, casting the parent will restore the original access.

Code example:

 public class Test { public static void main( String[] args ) { B b = new B(); A a = b; bf(); // "Access somewhat denied" af(); // "f()" } } class A { public static void f() { System.out.println("f()"); } } class B extends A { // *must* be public public static void f() { System.out.println("Access somewhat denied"); } } 
+1
source

So, I created a trivial test; IntelliJ really rejected this ... and Yes, I know: "this is a tool ... but I trust." Anyway, I went to javac, which emitted the same ERROR:

 Error:(...) java: ...Concrete.java:5: doSomethingStatic() in ...Concrete cannot override doSomethingStatic() in ...Base; attempting to assign weaker access privileges; was public 

Based on this and our skepticism in general, I suggest that the error be in your documentation.

Below is my sample code, I think is pretty final. It lingers on protected .

 public class Base { public static void doSomethingStatic(){} } public class Concrete extends Base { protected static void doSomethingStatic(){} } 
0
source

It can be hidden by an overloaded entry in a derived class:

 class Base { public static void doSomethingStatic(){} } class Derived extends Base { public static void doSomethingStatic(String arg){} } 

but only hidden to people who are trying to access it through a derived class.

-2
source

Source: https://habr.com/ru/post/1238681/


All Articles