Anonymous Inner classes and Final modifier [duplicate] - java

This question already has answers here:
Anonymous-Inner classes showing incorrect modifier
(4 answers)
Closed 3 years ago.
To my understand correctly anonymous classes are always final:
This has been mentioned specifically in JLS 15.9.5
However, when i run the following code to check that it is showing that Inner class is not final.
public class Test{
static class A<T> {
}
public static void main(String arg[]) {
A<Integer> obj = new A() {
};
if ((obj.getClass().getModifiers() & Modifier.FINAL) != 0) {
System.out.println("It is a final " + obj.getClass().getModifiers());
} else {
System.out.println("It is not final " + obj.getClass().getModifiers());
}
}
}
Output of above program is :
It is not final 0
Please clear my doubt as i am not able to understand this behavior.

I agree this may be considered a bug, given that other cases in the JLS exhibit a different behavior. Case in point is an interface: As per section 9.1.1.1:
Every interface is implicitly abstract.
And when running the below:
interface X {
void foo();
}
public static void main(String arg[]) {
System.out.println(Modifier.isAbstract(X.class.getModifiers()));
}
It returns true.
Another example is an enum where the JLS specifies:
An enum declaration is implicitly final unless it contains at least one enum constant that has a class body
And the below example is perfectly aligned with it.
enum X {
}
public static void main(String arg[]) {
System.out.println(Modifier.isFinal(X.class.getModifiers())); // true
}

Explicit is something what is written in the source code. So, if something is declared as public final class, it means that the class is explicitly final.
Implicit is something that is not written down in the source code, but that in the context of a certain construct or based on the language rules, an element behaves as it were declared with the specified modifier.
For example, the keyword enum in the declaration enum SomeEnum { } causes SomeEnum to be final, because the language rules prescribe it. Its effect is the same as the effect of the keyword final.
The example of an anonymous class being implicitly final is because no language construct exists to override an anonymous class. So it behaves as if it were final. I think the word "effectively" is better here.
However, you cannot make assumptions based on how reflection presents things. Consider the following snippet:
public class Test {
interface SomeInterface { }
abstract interface SomeAbstractInterface { }
static abstract class SomeAbstractClass { }
enum SomeEnum { }
public static void main(String arg[]) {
System.out.println(Modifier.toString(SomeInterface.class.getModifiers()));
System.out.println(Modifier.toString(SomeAbstractInterface.class.getModifiers()));
System.out.println(Modifier.toString(SomeAbstractClass.class.getModifiers()));
System.out.println(Modifier.toString(SomeEnum.class.getModifiers()));
}
}
The result is this:
abstract static interface
abstract static interface
abstract static
static final
Both interface and abstract interface are considered an abstract interface. They are also considered static by reflection. Apparently, in the process of parsing and compiling the Java source code, some modifiers could be removed or added.

JLS 15.9.5 "...implicitly final"... But that is not "final", what is meant is that you just can't extend an anonymous class. There is no syntactic construction for this, but the class is not marked as final.

Related

Require subclass to implement a static method [duplicate]

This question already has answers here:
Is there a way to make sure classes implementing an Interface implement static methods?
(9 answers)
Closed 2 years ago.
Coming from Python and Objective-C land, I may not fully understand what static methods are in Java, I think of them as "methods that operate on all members of the class" or "class-specific methods that are available when you don't have an instance of that class."
But is there a syntax for saying: "This abstract superclass requires each concrete subclass to implement this static method"? I know that static abstract isn't permitted, but it would conceptually be something like this:
public abstract class Lander {
#RequireImplmentationInSubclass // clearly my made-up name...
static abstract boolean probe(Radio radio);
}
public class MarsLander extends Lander {
static boolean probe(Radio radio) {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe(Radio radio) {
// ... some LunarLander specific implementation
}
}
update
... and somewhere else, a factory method does something like:
if (MarsLander.probe(radio)) {
... create an instance of MarsLander and work with it
} else if (LunarLander.probe(radio)) {
... create an instance of LunarLander and work with it
}
In my application, creating an instance invokes a lot of machinery, so I need to call probe() on a class method before I create an instance of the class.
I looked over Is there a way to make sure classes implementing an Interface implement static methods? and most of the responses were "why would you want to do that?".
I hope this example makes it clear(er). Perhaps there's' a more Java-esque way to remind the developer that a class-visible probe() method is required?
There is no way to require a static method.
But you can create a factory class with non-static methods:
public abstract class LanderFactory<L extends Lander> {
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
You can even have a registry of LanderFactory implementations, so they effectively act as singletons:
public abstract class LanderFactory<L extends Lander> {
private static final Map<Class<? extends Lander>,
LanderFactory<? extends Lander>> registry
= Map.of(MarsLander.class, new MarsLanderFactory(),
LunarLander.class, new LunarLanderFactory());
public static LanderFactory<? extends Lander> getInstance(
Class<? extends Lander> type) {
LanderFactory<? extends Lander> factory = registry.get(type);
if (factory == null) {
throw new IllegalArgumentException("No factory known for " + type);
}
return factory;
}
public abstract L createLander();
public abstract boolean probe(Radio radio);
}
public class MarsLanderFactory extends LanderFactory<MarsLander> {
#Override
public MarsLander createLander() {
return new MarsLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
public class LunarLanderFactory extends LanderFactory<LunarLander> {
#Override
public LunarLander createLander() {
return new LunarLander();
}
#Override
public boolean probe(Radio radio) {
// ...
}
}
"methods that operate on all members of the class"
This is not right. static methods operate on no members of a class.
Use of this is prohibited in static contexts.
I feel your question itself has the answer you are looking for. static abstract doesnt exists because on one hand you want it to behave differently (based on if it is a LunarProbe or a MarsProbe) and on the other hand you want it to be independent of the instance of LunarProbe and MarsProbe. static abstract contradicts itself.
Besides
static boolean probe() {
// ... some MarsLander specific implementation
// what goes here? you dont have access to any instance of this class.
}
static abstract violates a tenet of OOP called polymorphism.
I tried your code(and other things surrounding this), and I'd like to tell you there's a way but I don't think there is.
I would instead recommend using a utility class that supports this static functionality you're looking for.For example, a LanderUtility class that has static methods in it might solve this in a reasonable way.
Mostly though, I don't think of using static methods in that way in Java. The real power in what is going on with this abstract class is that you can count on(somewhat) a certain type of behavior from a child. Notably, for this to matter, the child needs to be instantiated in the first place and you can use a normal, non-static method and have the child implement that instead.
In Java, static methods is allowed to be invoked directly on class references. It does not matter whether it is a abstract class or a normal class.
Due to this reason, static and abstract modifiers can't be used together. Otherwise, what would be the output of this code if the lander method is not implemented ? That's why it is illegal.
Lander.probe();
But, I think we can throw an exception from our super class static method with some hint in the exception message. We can enforce implementation of the static method.
public abstract class Lander {
static boolean probe() {
throw new RuntimeException("Oh oh !!! Why am I here ??");
}
}
public class MarsLander extends Lander {
static boolean probe() {
// ... some MarsLander specific implementation
}
}
public class LunarLander extends Lander {
static boolean probe() {
// ... some LunarLander specific implementation'
}
}
That way, if there is a Lander implementation which has not implemented a static probe method, the probe method will get inherited but this will throw a run time exception.
Methods can't be both abstract and static, because abstract methods have to be overridden, and static methods in Java cannot be overridden. Which class implementation of a static method is used is determined at compile time. You can declare a static method with the same signature in a subclass, but it is not considered overriding because there won’t be any run-time polymorphism. The static method of the superclass is 'masked' in the subclass. If a derived class defines a static method with the same signature as a static method in the base class, the method in the derived class hides the method in the base class.

static method in class have same signature as default method in interface

I have below scenario :
class C {
static void m1() {}
}
interface I {
default void m1() {}
}
//this will give compilation error : inherited method from C cannot hide public abstract method in I
class Main extends C implements I {
}
Below are my questions:
I am aware that instance method will override the default methods but what if static methods in class have same signature as default method in Interface?
If static method m1() in class C would be public then compilation error will be :
static method m1() conflicts with abstract method in I.
so when the access modifier was default it was trying to hide and when it is public it is conflicting. why is this difference? what is the concept behind it?
Ultimately that boils down to the fact that when you have something like this:
class Me {
public static void go() {
System.out.println("going");
}
}
These both would be allowed:
Me.go();
Me meAgain = new Me();
meAgain.go(); // with a warning here
Intersting is that this would work too for example:
Me meAgain = null;
meAgain.go();
Personally I still see this as design flaw that could not be retracted due to compatibility - but I wish the compiler would not allow me to access the static method from an instance.
Your first question is not related to java-8 per-se, it has been like this before java-8:
interface ITest {
public void go();
}
class Test implements ITest {
public static void go() { // fails to compile
}
}
default methods just follow the same rule here. Why this happens is actually detailed quite a lot on stack overflow - but the underlying idea is that potentially this would cause confusion on which method to call (imagine ITest would be a class that Test would extends and you do ITest test = new Test(); test.go(); -> which method are you calling?)
I think that for the same reasons this is not allowed also (which is basically your second question, otherwise you would have a static and non-static method with the same signatures)
static class Me {
static void go() {
}
void go() {
}
}
It's interesting that this is sort of fixed (I guess that they realized it would be really bad to do the same mistake again) in method references:
static class Mapper {
static int increment(int x) {
return x + 1;
}
int decrement(int x) {
return x - 1;
}
}
Mapper m = new Mapper();
IntStream.of(1, 2, 3).map(m::increment); // will not compile
IntStream.of(1, 2, 3).map(m::decrement); // will compile
Answering your 1st question:
Both the "static method in class" and the "default method in interface" are available to the class Main, and hence if they have the same signature, it will create ambiguity.
For example:
class C{
static void m1(){System.out.println("m1 from C");}
}
public class Main extends C{
public static void main(String[] args) {
Main main=new Main();
main.m1();
}
}
Output: m1 from C
Similarly,
interface I{
default void m1(){System.out.println("m1 from I");}
}
public class Main implements I{
public static void main(String[] args) {
Main main=new Main();
main.m1();
}
}
Output: m1 from I
As you can see, both these can be accessed similarly. So this is also the reason for conflict when you implement I and extend C.
Answering your second question:
If your classed and interfaces are in the same package, the default and public access modifier should work similarly.
Also, m1() in C is static which cannot be overridden, and hence it cannot be considered as implementation of m1() in I and so the compilation issue.
Hope that helps!
I will answer your first question since the second is already answered
I am aware that instance method will override the default methods but
what if static methods in class have same signature as default method
in Interface?
I am assuming you are using JDK 1.8 and hence the confusion. default modifier in an interface method is not talking about its access specifications. Instead it mentions that the interface itself need to implement this method. Access specification for the method is still public. Starting from JDK8 , interfaces allow you specify methods with default modifer to allow to extend interfaces in a backward compatible way.
In your interface you had to give default void m1() {} for the compilation to be successfull. Normally we simply define them in an abstract way like void m1(); in an interface You had to implement the method because you specified the method as default. Hope you understand.
Because class methods in java can also be called using instance variables, this construct will lead to ambiguities:
Main m = new Main();
m.m1();
It is unclear if the last statement should call the class method C.m1() or the instance method I.m1().

same final variable declared in two interface and implemented in one class

Hi I have two interface Ainterface and Binterface having same static final variable as 'i' which is declared as 10 and 20 respectively, I am implementing these two interfaces two my class InterfaceCheck where I am declaring same interface variable as static and final and initialized to 30. When I try to print the value of i in my class I am getting 30 as output. can some one explain me why I am able to reinitialize i to some other value even though its a final variable.
CODE
public interface Ainterface {
public final static int i=10;
}
public interface Binterface {
public static final int i=20;
}
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
}
}
>> output : 30
Class fields are always resolved on the static type of the reference.
In
public static void main(String[] args) {
System.out.println(i);
}
it implicitly does
System.out.println(InterfaceCheck.i);
so that is what you see.
Also, static fields are not inherited.
Static variables belong to the class itself (not to the instance) and these variables are not inherited by child class or implementing class.
Therefore:
public class InterfaceCheck implements Ainterface,Binterface {
public static final int i=30;
}
is not overriding i from those 2 interfaces. It is actually declaring a new independent static final variable.
Java has single inheritance because multiple inheritance has the problem of which members to pick when inherited classes collide on member names. But Java provides interfaces because that provides much of the power of multiple inheritance (additional behaviors) without the risk of name collision (but at the cost of choosing which methods so provide when method signature collision occurs).
Allowing class variables in interfaces is a relaxation of this rule, but was probably allowed because of where the member variable is located (one per class). As anubhava and Sotirios said they are not inherited, but declaring a new member, obscuring the inherited variable.
Your question concerns lexical scope. Since you have declared three 'public' variables which are class members, then you need to resolve scope. Since you have two inherited interfaces, do you really mean to define/set your own class variable, or to modify one or both of the inherited interface class variables?
I recommend you play around with the code to understand it fully whats going on, Very old thread here but all the same just wanted to add the following:
Comment out the static class "i" and when you run the code you will see java telling you "reference to i is ambiguous" ie, it does not know which one you want to call as it exists in both interfaces. Now un-comment the class static "i" and add two more printouts with the reference to both interfaces. As they are static this is allowed.
public static final int i=30;
public static void main(String[] args) {
System.out.println(i);
System.out.println(Ainterface.i);
System.out.println(Binterface.i);
}
30
10
20
Again if you remove the InterfaceCheck class static "i" constant and remove one of the interfaces it implements, say Binterface. You can reference the constant from Ainterface without its explicit reference as its the only static "i" created.
public class InterfaceCheck implements Ainterface {
public static void main(String[] args) {
System.out.println(i); //This will out Ainterface.i value of 10
//System.out.println(Ainterface.i);
//System.out.println(Binterface.i);
}

How to define nested static classes with static methods, inherited from a nested interface in Java?

I have a Java problem with nested classes.
My first class structure looked like this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private interface NestedClass {
public void method();
}
private class NestedClass1 {
public void method() {
}
}
private class NestedClass2 {
public void method(){
}
}
}
But now I want these method() methods to be static because they should be principally.
I cannot make them static without having them in a static class, but that's no problem, I made the classes static, they should be anyway.
It looks like this right now:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static interface NestedClass {
public void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But then the trouble begins. A static method does not inherit correctly from a non-static interface method, as I get this message This static method cannot hide the instance method from TopClass.NestedClass in Eclipse.
When I make the interface method static, it gives me this error: Illegal modifier for the interface method method; only public & abstract are permitted
So I thought of an abstract class, and tried this:
public class TopClass {
public void mainMethod() {
// uses the different "method" methods from
// NestedClass-implementing nested classes
}
private static abstract class NestedClass {
public static abstract void method();
}
private static class NestedClass1 {
public static void method() {
}
}
private static class NestedClass2 {
public static void method(){
}
}
}
But again, seemingly abstract methods cannot be declared static: The abstract method method in type NestedClass can only set a visibility modifier, one of public or protected.
Leaving the static away (in the abstract class method), errors this on the method methods in the NestedClass1 & 2: This static method cannot hide the instance method from TopClass.NestedClass.
Isn't there any way to declare some kind of superstructure for covering static methods?
EDIT:
The problem I actually try to solve it the lack of possibility of Java for storing references to methods. So instead I have those classes everyone with just one method, but to store them in a List f.e. they must be able to be "caught" by a superstructure.
I got the hint to try anonymous classes or enums, gonna try that now.
Interfaces and statics don't go together. At all. There is no Java support for creating / imposing patterns on static methods.
A static method declaration must always be followed by a definition. It cannot be implemented by subclasses.
I think you're just not approaching your problem right. Try a different approach!
Make NestedClass an interface NestedInterface and store your different implementations as anonymous classes implementing this interface:
public static final NestedInterface firstNested = new NestedInterface() {
#Override
public void method() {
// ...
}
};
Make NestedClass an enumeration NestedEnum and store your different implementations as enumeration values implementing an abstract method from the enumeration. This only works if you have a fixed number of implementations you which to choose from and you do not want to accept NestedClass implementations from outside sources.
public enum NestedEnum {
FIRST {
#Override
public void method() {
// ...
}
};
public abstract void method();
}
EDIT: In reply to your comment:
The classes itself are static as well..
static in the context of a nested class means that this class can be instantiated without an instance of the containing class.
A regular nested class such as in your first example can be instantiated through TopClass.this.new NestedClass1(). Normally you'd simply write new NestedClass1() from within the constructor or an instance method of TopClass, but in this verbose form you can clearly see the dependence on TopClass.this. This can also be seen from any method of NestedClass1, as you have access to the containing class with TopClass.this.
A static nested class such as in your second example can be instantiated through new TopClass.NestedClass1(). Once again, you could just write new NestedClass1() but the verbose form clearly shows that the construction only depends on TopClass and is not associated with an instance of TopClass. You could even create an instance from an outside class using the same snippet new TopClass.NestedClass1() without ever creating a TopClass instance.
I suggest you take a look at this question on inner classes and static nested classes.
The fact the your interface/abstract class is nested is irrelevant to the problem.
You just can't. There is no way in Java to enforce some class to implement static methods. Just cry and surrender and use instance methods.
static abstract is a contradiction. Static methods are not like other languages' class methods. When you make a static method it goes on a single class, it doesn't get inherited by or have its implementation deferred to subclasses.
You don't explain why you want these methods to be static. If you want these methods to be defined by subclasses then they shouldn't be.

Why can't static methods be abstract in Java?

The question is in Java why can't I define an abstract static method? for example
abstract class foo {
abstract void bar( ); // <-- this is ok
abstract static void bar2(); //<-- this isn't why?
}
Because "abstract" means: "Implements no functionality", and "static" means: "There is functionality even if you don't have an object instance". And that's a logical contradiction.
Poor language design. It would be much more effective to call directly a static abstract method than creating an instance just for using that abstract method. Especially true when using an abstract class as a workaround for enum inability to extend, which is another poor design example. Hope they solve those limitations in a next release.
You can't override a static method, so making it abstract would be meaningless. Moreover, a static method in an abstract class would belong to that class, and not the overriding class, so couldn't be used anyway.
The abstract annotation to a method indicates that the method MUST be overriden in a subclass.
In Java, a static member (method or field) cannot be overridden by subclasses (this is not necessarily true in other object oriented languages, see SmallTalk.) A static member may be hidden, but that is fundamentally different than overridden.
Since static members cannot be overriden in a subclass, the abstract annotation cannot be applied to them.
As an aside - other languages do support static inheritance, just like instance inheritance. From a syntax perspective, those languages usually require the class name to be included in the statement. For example, in Java, assuming you are writing code in ClassA, these are equivalent statements (if methodA() is a static method, and there is no instance method with the same signature):
ClassA.methodA();
and
methodA();
In SmallTalk, the class name is not optional, so the syntax is (note that SmallTalk does not use the . to separate the "subject" and the "verb", but instead uses it as the statemend terminator):
ClassA methodA.
Because the class name is always required, the correct "version" of the method can always be determined by traversing the class hierarchy. For what it's worth, I do occasionally miss static inheritance, and was bitten by the lack of static inheritance in Java when I first started with it. Additionally, SmallTalk is duck-typed (and thus doesn't support program-by-contract.) Thus, it has no abstract modifier for class members.
I also asked the same question , here is why
Since Abstract class says, it will not give implementation and allow subclass to give it
so Subclass has to override the methods of Superclass ,
RULE NO 1 - A static method cannot be overridden
Because static members and methods are compile time elements , that is why Overloading(Compile time Polymorphism) of static methods are allowed rather then Overriding (Runtime Polymorphism)
So , they cant be Abstract .
There is no thing like abstract static <--- Not allowed in Java Universe
This is a terrible language design and really no reason as to why it can't be possible.
In fact, here is a pattern or way on how it can be mimicked in **Java ** to allow you at least be able to modify your own implementations:
public static abstract class Request {
// Static method
public static void doSomething() {
get().doSomethingImpl();
}
// Abstract method
abstract void doSomethingImpl();
/////////////////////////////////////////////
private static Request SINGLETON;
private static Request get() {
if ( SINGLETON == null ) {
// If set(request) is never called prior,
// it will use a default implementation.
return SINGLETON = new RequestImplementationDefault();
}
return SINGLETON;
}
public static Request set(Request instance){
return SINGLETON = instance;
}
/////////////////////////////////////////////
}
Two implementations:
/////////////////////////////////////////////////////
public static final class RequestImplementationDefault extends Request {
#Override void doSomethingImpl() {
System.out.println("I am doing something AAA");
}
}
/////////////////////////////////////////////////////
public static final class RequestImplementaionTest extends Request {
#Override void doSomethingImpl() {
System.out.println("I am doing something BBB");
}
}
/////////////////////////////////////////////////////
Could be used as follows:
Request.set(new RequestImplementationDefault());
// Or
Request.set(new RequestImplementationTest());
// Later in the application you might use
Request.doSomething();
This would allow you to invoke your methods statically, yet be able to alter the implementation say for a Test environment.
Theoretically, you could do this on a ThreadLocal as well, and be able to set instance per Thread context instead rather than fully global as seen here, one would then be able to do Request.withRequest(anotherRequestImpl, () -> { ... }) or similar.
Real world usually do not require the ThreadLocal approach and usually it is enough to be able to alter implementation for Test environment globally.
Note, that the only purpose for this is to enable a way to retain the ability to invoke methods DIRECTLY, EASILY and CLEANLY which static methods provides while at the same time be able to switch implementation should a desire arise at the cost of slightly more complex implementation.
It is just a pattern to get around having normally non modifiable static code.
An abstract method is defined only so that it can be overridden in a subclass. However, static methods can not be overridden. Therefore, it is a compile-time error to have an abstract, static method.
Now the next question is why static methods can not be overridden??
It's because static methods belongs to a particular class and not to its instance. If you try to override a static method you will not get any compilation or runtime error but compiler would just hide the static method of superclass.
A static method, by definition, doesn't need to know this. Thus, it cannot be a virtual method (that is overloaded according to dynamic subclass information available through this); instead, a static method overload is solely based on info available at compile time (this means: once you refer a static method of superclass, you call namely the superclass method, but never a subclass method).
According to this, abstract static methods would be quite useless because you will never have its reference substituted by some defined body.
I see that there are a god-zillion answers already but I don't see any practical solutions. Of course this is a real problem and there is no good reason for excluding this syntax in Java. Since the original question lacks a context where this may be need, I provide both a context and a solution:
Suppose you have a static method in a bunch of classes that are identical. These methods call a static method that is class specific:
class C1 {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
private static void doMoreWork(int k) {
// code specific to class C1
}
}
class C2 {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
private static void doMoreWork(int k) {
// code specific to class C2
}
}
doWork() methods in C1 and C2 are identical. There may be a lot of these calsses: C3 C4 etc. If static abstract was allowed, you'd eliminate the duplicate code by doing something like:
abstract class C {
static void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
static abstract void doMoreWork(int k);
}
class C1 extends C {
private static void doMoreWork(int k) {
// code for class C1
}
}
class C2 extends C {
private static void doMoreWork(int k) {
// code for class C2
}
}
but this would not compile because static abstract combination is not allowed.
However, this can be circumvented with static class construct, which is allowed:
abstract class C {
void doWork() {
...
for (int k: list)
doMoreWork(k);
...
}
abstract void doMoreWork(int k);
}
class C1 {
private static final C c = new C(){
#Override void doMoreWork(int k) {
System.out.println("code for C1");
}
};
public static void doWork() {
c.doWork();
}
}
class C2 {
private static final C c = new C() {
#Override void doMoreWork(int k) {
System.out.println("code for C2");
}
};
public static void doWork() {
c.doWork();
}
}
With this solution the only code that is duplicated is
public static void doWork() {
c.doWork();
}
Assume there are two classes, Parent and Child. Parent is abstract. The declarations are as follows:
abstract class Parent {
abstract void run();
}
class Child extends Parent {
void run() {}
}
This means that any instance of Parent must specify how run() is executed.
However, assume now that Parent is not abstract.
class Parent {
static void run() {}
}
This means that Parent.run() will execute the static method.
The definition of an abstract method is "A method that is declared but not implemented", which means it doesn't return anything itself.
The definition of a static method is "A method that returns the same value for the same parameters regardless of the instance on which it is called".
An abstract method's return value will change as the instance changes. A static method will not. A static abstract method is pretty much a method where the return value is constant, but does not return anything. This is a logical contradiction.
Also, there is really not much of a reason for a static abstract method.
An abstract class cannot have a static method because abstraction is done to achieve DYNAMIC BINDING while static methods are statically binded to their functionality.A static method means
behavior not dependent on an instance variable, so no instance/object
is required.Just the class.Static methods belongs to class and not object.
They are stored in a memory area known as PERMGEN from where it is shared with every object.
Methods in abstract class are dynamically binded to their functionality.
Declaring a method as static means we can call that method by its class name and if that class is abstract as well, it makes no sense to call it as it does not contain any body, and hence we cannot declare a method both as static and abstract.
As abstract methods belong to the class and cannot be overridden by the implementing class.Even if there is a static method with same signature , it hides the method ,does not override it.
So it is immaterial to declare the abstract method as static as it will never get the body.Thus, compile time error.
A static method can be called without an instance of the class. In your example you can call foo.bar2(), but not foo.bar(), because for bar you need an instance.
Following code would work:
foo var = new ImplementsFoo();
var.bar();
If you call a static method, it will be executed always the same code. In the above example, even if you redefine bar2 in ImplementsFoo, a call to var.bar2() would execute foo.bar2().
If bar2 now has no implementation (that's what abstract means), you can call a method without implementation. That's very harmful.
I believe I have found the answer to this question, in the form of why an interface's methods (which work like abstract methods in a parent class) can't be static. Here is the full answer (not mine)
Basically static methods can be bound at compile time, since to call them you need to specify a class. This is different than instance methods, for which the class of the reference from which you're calling the method may be unknown at compile time (thus which code block is called can only be determined at runtime).
If you're calling a static method, you already know the class where it's implemented, or any direct subclasses of it. If you define
abstract class Foo {
abstract static void bar();
}
class Foo2 {
#Override
static void bar() {}
}
Then any Foo.bar(); call is obviously illegal, and you will always use Foo2.bar();.
With this in mind, the only purpose of a static abstract method would be to enforce subclasses to implement such a method. You might initially think this is VERY wrong, but if you have a generic type parameter <E extends MySuperClass> it would be nice to guarantee via interface that E can .doSomething(). Keep in mind that due to type erasure generics only exist at compile time.
So, would it be useful? Yes, and maybe that is why Java 8 is allowing static methods in interfaces (though only with a default implementation). Why not abstract static methods with a default implementation in classes? Simply because an abstract method with a default implementation is actually a concrete method.
Why not abstract/interface static methods with no default implementation? Apparently, merely because of the way Java identifies which code block it has to execute (first part of my answer).
Because abstract class is an OOPS concept and static members are not the part of OOPS....
Now the thing is we can declare static complete methods in interface and we can execute interface by declaring main method inside an interface
interface Demo
{
public static void main(String [] args) {
System.out.println("I am from interface");
}
}
Because abstract mehods always need implementation by subclass.But if you make any method to static then overriding is not possible for this method
Example
abstract class foo {
abstract static void bar2();
}
class Bar extends foo {
//in this if you override foo class static method then it will give error
}
Static Method
A static method can be invoked without the need for creating an instance of a class.A static method belongs to the class rather than the object of a class.
A static method can access static data member and also it can change the value of it.
Abstract Keyword is used to implement abstraction.
A static method can't be overriden or implemented in child class. So, there is no use of making static method as abstract.
The idea of having an abstract static method would be that you can't use that particular abstract class directly for that method, but only the first derivative would be allowed to implement that static method (or for generics: the actual class of the generic you use).
That way, you could create for example a sortableObject abstract class or even interface
with (auto-)abstract static methods, which defines the parameters of sort options:
public interface SortableObject {
public [abstract] static String [] getSortableTypes();
public String getSortableValueByType(String type);
}
Now you can define a sortable object that can be sorted by the main types which are the same for all these objects:
public class MyDataObject implements SortableObject {
final static String [] SORT_TYPES = {
"Name","Date of Birth"
}
static long newDataIndex = 0L ;
String fullName ;
String sortableDate ;
long dataIndex = -1L ;
public MyDataObject(String name, int year, int month, int day) {
if(name == null || name.length() == 0) throw new IllegalArgumentException("Null/empty name not allowed.");
if(!validateDate(year,month,day)) throw new IllegalArgumentException("Date parameters do not compose a legal date.");
this.fullName = name ;
this.sortableDate = MyUtils.createSortableDate(year,month,day);
this.dataIndex = MyDataObject.newDataIndex++ ;
}
public String toString() {
return ""+this.dataIndex+". "this.fullName+" ("+this.sortableDate+")";
}
// override SortableObject
public static String [] getSortableTypes() { return SORT_TYPES ; }
public String getSortableValueByType(String type) {
int index = MyUtils.getStringArrayIndex(SORT_TYPES, type);
switch(index) {
case 0: return this.name ;
case 1: return this.sortableDate ;
}
return toString(); // in the order they were created when compared
}
}
Now you can create a
public class SortableList<T extends SortableObject>
that can retrieve the types, build a pop-up menu to select a type to sort on and resort the list by getting the data from that type, as well as hainv an add function that, when a sort type has been selected, can auto-sort new items in.
Note that the instance of SortableList can directly access the static method of "T":
String [] MenuItems = T.getSortableTypes();
The problem with having to use an instance is that the SortableList may not have items yet, but already need to provide the preferred sorting.
Cheerio,
Olaf.
First, a key point about abstract classes -
An abstract class cannot be instantiated (see wiki). So, you can't create any instance of an abstract class.
Now, the way java deals with static methods is by sharing the method with all the instances of that class.
So, If you can't instantiate a class, that class can't have abstract static methods since an abstract method begs to be extended.
Boom.
As per Java doc:
A static method is a method that is associated with the class in which
it is defined rather than with any object. Every instance of the class
shares its static methods
In Java 8, along with default methods static methods are also allowed in an interface. This makes it easier for us to organize helper methods in our libraries. We can keep static methods specific to an interface in the same interface rather than in a separate class.
A nice example of this is:
list.sort(ordering);
instead of
Collections.sort(list, ordering);
Another example of using static methods is also given in doc itself:
public interface TimeClient {
// ...
static public ZoneId getZoneId (String zoneString) {
try {
return ZoneId.of(zoneString);
} catch (DateTimeException e) {
System.err.println("Invalid time zone: " + zoneString +
"; using default time zone instead.");
return ZoneId.systemDefault();
}
}
default public ZonedDateTime getZonedDateTime(String zoneString) {
return ZonedDateTime.of(getLocalDateTime(), getZoneId(zoneString));
}
}
Because 'abstract' means the method is meant to be overridden and one can't override 'static' methods.
Regular methods can be abstract when they are meant to be overridden by subclasses and provided with functionality.
Imagine the class Foo is extended by Bar1, Bar2, Bar3 etc. So, each will have their own version of the abstract class according to their needs.
Now, static methods by definition belong to the class, they have nothing to do with the objects of the class or the objects of its subclasses. They don't even need them to exist, they can be used without instantiating the classes. Hence, they need to be ready-to-go and cannot depend on the subclasses to add functionality to them.
Because abstract is a keyword which is applied over Abstract methods do not specify a body. And If we talk about static keyword it belongs to class area.
because if you are using any static member or static variable in class it will load at class loading time.
There is one occurrence where static and abstract can be used together and that is when both of these modifiers are placed in front of a nested class.
In a single line, this dangerous combination (abstract + static) violates the object-oriented principle which is Polymorphism.
In an inheritance situation, the JVM will decide at runtime by the implementation in respect of the type of instance (runtime polymorphism) and not in respect of the type of reference variable (compile-time polymorphism).
With #Overriding:
Static methods do not support #overriding (runtime polymorphism), but only method hiding (compile-time polymorphism).
With #Hiding:
But in a situation of abstract static methods, the parent (abstract) class does not have implementation for the method. Hence, the child type reference is the only one available and it is not polymorphism.
Child reference is the only one available:
For this reason (suppress OOPs features), Java language considers abstract + static an illegal (dangerous) combination for methods.
You can do this with interfaces in Java 8.
This is the official documentation about it:
https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html
Because if a class extends an abstract class then it has to override abstract methods and that is mandatory. And since static methods are class methods resolved at compile time whereas overridden methods are instance methods resolved at runtime and following dynamic polymorphism.

Categories