From another question I have learnt that it is possible in Java to define specific methods for each one of the instances of an Enum:
public class AClass {
private enum MyEnum{
A { public String method1(){ return null; } },
B { public Object method2(String s){ return null; } },
C { public void method3(){ return null; } } ;
}
...
}
I was surprised that this is even possible, do this "exclusive methods" specific to each instance have a name to look for documentation?
Also, how is it supposed to be used? Because the next is not compiling:
private void myMethod () {
MyEnum.A.method1();
}
How am I supposed to use these "exclusive" methods?
You need to declare abstract methods in your enum which are then implemented in specific enum instances.
class Outer {
private enum MyEnum {
X {
public void calc(Outer o) {
// do something
}
},
Y {
public void calc(Outer o) {
// do something different
// this code not necessarily the same as X above
}
},
Z {
public void calc(Outer o) {
// do something again different
// this code not necessarily the same as X or Y above
}
};
// abstract method
abstract void calc(Outer o);
}
public void doCalc() {
for (MyEnum item : MyEnum.values()) {
item.calc(this);
}
}
}
You cannot refer to those methods, because you are effectively creating anonymous (*) class for each enum. As it is anonymous, you can reference such methods only from inside your anonymous class itself or through reflection.
This technique is mostly useful when you declare abstract method in your enumeration, and implement that method for each enum individually.
(*) JLS 8.9 Enums part says: "The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type."
Each enum is an anonymous inner class. So like any anonymous inner class, you can add all of the methods you want, but there is no way to reference them outside of the class, as the class doesn't have a type that defines the methods.
The advantage of allowing methods on the enum implementation is that it allows for a strategy pattern, where the enum itself has an abstract method or a default implementation, and specific members of the enum have implementations of that method that may do something different.
I have used this technique to greatly reduce code complexity on switch statements. Instead of switching on the enum in some other class, just get a reference to it and call a method, and let the enum itself take care of it. Of course that depends on the scenario if it makes sense, but it can reduce code complexity tremendously.
So I've run across something interesting which is incredibly useful. In an enum you can define an abstract method which each of the enum values is forced to provide an implementation for. For example, the following:
public enum Test {
RAWR ("Burninating the country side") {
#Override
public int doStuff() {
return 0;
}
};
private final String enumStuff;
private Test(String enumStuff) {
this.enumStuff = enumStuff;
}
public abstract int doStuff();
}
I added the private variable so you could see how it works in relation to the standard private constructor.
So this makes me wonder: what is RAWR actually, in relation to the Test class? Normally, this kind of syntax would make me think that I'm defining an anonymous inner class, but that doesn't seem intuitive here, since RAWR is anything but anonymous.
The closest thing I can think of is that the values of an enum are in fact extensions of the enum itself, e.g.,
public class RAWR extends Test {
#Override
public int doStuff() {
return 0;
}
}
So, does anyone know what's really going on with this?
From the JLS
An enum declaration specifies a new enum type, a special kind of class type.
[...]
The optional class body of an enum constant implicitly defines an
anonymous class declaration (§15.9.5) that extends the immediately
enclosing enum type.
The JLS also states
For each enum constant c declared in the body of the declaration of E,
E has an implicitly declared public static final field of type E that
has the same name as c. The field has a variable initializer
consisting of c, and is annotated by the same annotations as c.
The enum type you declare is Test. Every enum constant you declare is an instance of a subclass of Test, if it has a body.
Note that enum types are also implicitly final (you wouldn't be able to subclass them). The Java Language only allows this subclassing behavior for enum constants.
This is a very powerful feature of enums, in that not only is each enum a fully fledged class that can have constructors, setters, getters etc but each individual member of the enum can have its own anonymous implementation of the main enum class.
You actually are defining anonymous inner classes. Execute javap -c <classFile> on the class file of your enum to see how the enum looks when compiled.
You will see that an enum is nothing more than a normal class with public static final variables of the same type as the enum. You will also see that for each variable an anonymous inner class is assigned.
Example:
$ javap-c StatusCode.class
public final class de.haufe.StatusCode extends java.lang.Enum<de.haufe.StatusC ode> {
public static final de.haufe.StatusCode CREATED;
public static final de.haufe.StatusCode BAD_REQUEST;
public static final de.haufe.StatusCode UNAUTHORIZED;
public static final de.haufe.StatusCode NOT_FOUND;
public static final de.haufe.StatusCode PRECONDITION_FAILED;
public static final de.haufe.StatusCode UNSUPPORTED_MEDIA_TYPE;
public static final de.haufe.StatusCode UNPROCESSABLE_ENTITY;
public static final de.haufe.StatusCode LOCKED;
public static final de.haufe.StatusCode INTERNAL_SERVER_ERROR;
public static de.haufe.StatusCode[] values();
}
// more stuff
So this is not the best example because none of the enum value implements a method but you may get an idea what an enum actually is.
If you've ever used enums in generics you will have come across E extends Enum<E> which is the right way of defining the type of an enum. It's a little weird but once you get your head around it you can see that it is saying that an enum actually extends an Enum (note the different case) of itself. So essentially yes, all enums in the group seem to extend the base declaring class but the base declaring class is actually an Enum - sort of.
BTW - You can also make enums implement an interface:
interface Something {
int getValue();
}
enum It implements Something {
One,
Two,
Three;
#Override
public int getValue() {
return ordinal();
}
}
From another question I have learnt that it is possible in Java to define specific methods for each one of the instances of an Enum:
public class AClass {
private enum MyEnum{
A { public String method1(){ return null; } },
B { public Object method2(String s){ return null; } },
C { public void method3(){ return null; } } ;
}
...
}
I was surprised that this is even possible, do this "exclusive methods" specific to each instance have a name to look for documentation?
Also, how is it supposed to be used? Because the next is not compiling:
private void myMethod () {
MyEnum.A.method1();
}
How am I supposed to use these "exclusive" methods?
You need to declare abstract methods in your enum which are then implemented in specific enum instances.
class Outer {
private enum MyEnum {
X {
public void calc(Outer o) {
// do something
}
},
Y {
public void calc(Outer o) {
// do something different
// this code not necessarily the same as X above
}
},
Z {
public void calc(Outer o) {
// do something again different
// this code not necessarily the same as X or Y above
}
};
// abstract method
abstract void calc(Outer o);
}
public void doCalc() {
for (MyEnum item : MyEnum.values()) {
item.calc(this);
}
}
}
You cannot refer to those methods, because you are effectively creating anonymous (*) class for each enum. As it is anonymous, you can reference such methods only from inside your anonymous class itself or through reflection.
This technique is mostly useful when you declare abstract method in your enumeration, and implement that method for each enum individually.
(*) JLS 8.9 Enums part says: "The optional class body of an enum constant implicitly defines an anonymous class declaration (§15.9.5) that extends the immediately enclosing enum type."
Each enum is an anonymous inner class. So like any anonymous inner class, you can add all of the methods you want, but there is no way to reference them outside of the class, as the class doesn't have a type that defines the methods.
The advantage of allowing methods on the enum implementation is that it allows for a strategy pattern, where the enum itself has an abstract method or a default implementation, and specific members of the enum have implementations of that method that may do something different.
I have used this technique to greatly reduce code complexity on switch statements. Instead of switching on the enum in some other class, just get a reference to it and call a method, and let the enum itself take care of it. Of course that depends on the scenario if it makes sense, but it can reduce code complexity tremendously.
What is the reason of declaring a member of a private inner class public in Java if it still can't be accessed outside of containing class? Or can it?
public class DataStructure {
// ...
private class InnerEvenIterator {
// ...
public boolean hasNext() { // Why public?
// ...
}
}
}
If the InnerEvenIterator class does not extend any class or implement any interface, I think it is nonsense because no other class can access any instance of it.
However, if it extends or implements any other non private class or interface, it makes sense. An example:
interface EvenIterator {
public boolean hasNext();
}
public class DataStructure {
// ...
private class InnerEvenIterator implements EvenIterator{
// ...
public boolean hasNext() { // Why public?
// ...
}
}
InnerEvenIterator iterator;
public EvenIterator getIterator(){
return iterator;
}
}
This method can be made public in order to indicate that it's semantically public, despite the fact that compiler doesn't enforce visibility rules in this particular case.
Imagine that during some refactoring you need to make this inner class top-level. If this method is private, how would you decide whether it should be made public, or some more restrictive modifier should be used? Declaring method as public tells reader the intentions of original author - this method shouldn't be considered an implementation detail.
It is useful when you implement any interface.
class DataStructure implements Iterable<DataStructure> {
#Override
public Iterator<DataStructure> iterator() {
return new InnerEvenIterator();
}
// ...
private class InnerEvenIterator implements Iterator<DataStructure> {
// ...
public boolean hasNext() { // Why public?
// ...
return false;
}
#Override
public DataStructure next() {
throw new UnsupportedOperationException("Not supported yet.");
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public static void main(String[] ex) {
DataStructure ds = new DataStructure();
Iterator<DataStructure> ids = ds.iterator();
ids.hasNext(); // accessable
}
}
I think you are missing the implementing the Iterator interface part in your sample code. In that case, you can't make the hasNext() method have any other visibility identifier other than public since that would end up reducing its visibility (interface methods have public visibility) and it won't compile.
There are many combinations of access modifiers which are not useful. A public method in a private inner class is only useful if it implements a public method in a public class/interface.
public class DataStructure {
// ...
private class InnerEvenIterator implements Iterator {
// ...
public boolean hasNext() { // Why public?
// ...
}
}
public Iterator iterator() {
return new InnerEvenIterator();
}
}
BTW: abstract classes often have public constructors when actually they are protected
If the inner class is private it cannot be accessed by name outside of the outer class. Inner and outer classes have access to each other's private methods and private instance variables. As long as you are within the inner or outer class, the modifiers public and private have the same effect. In your code example:
public class DataStructure {
// ...
private class InnerEvenIterator {
// ...
public boolean hasNext() { // Why public?
// ...
}
}
}
As far as the class DataStructure is concerned, this is completely equivalent to:
public class DataStructure {
// ...
private class InnerEvenIterator {
// ...
private boolean hasNext() {
// ...
}
}
}
This is because only DataStructure can access it, so it doesn't matter if you set it to public or private. Either way, DataStructure is still the only class that can access it. Use whichever modifier you like, it makes no functional difference. The only time you can't choose at random is when you are implementing or extending, in which case you can't reduce the access, but you can increase it. So if an abstract method has protected access you can change it to public. Granted neither one actually makes any difference.
If you plan on using an inner class in other classes, and therefore making it public, you probably shouldn't make it an inner class in the first place.
Additionally, I don't see any requirement for inner classes extending or implementing other classes. It might be common for them to do so, but it's certainly not required.
There are multiple aspects which have to be considered here. The following will use the term "nested class" because it covers both non-static (also called "inner class") and static classes (source).
Not related to private nested classes, but JLS §8.2 has an interesting example which shows where public members in package-private or protected classes could be useful.
Source code
Overriding methods
When your nested class implements an interface or extends a class and overrides one of its methods, then per JLS §8.4.8.3:
The access modifier of an overriding or hiding method must provide at least as much access as the overridden or hidden method
For example:
public class Outer {
private static class Nested implements Iterator<String> {
#Override
public boolean hasNext() {
...
}
#Override
public String next() {
...
}
}
}
The methods hasNext() and next() which override the Iterator methods have to be public because the Iterator methods are public.
As a side note: JLS §13.4.7 describes that it is possible for a class to increase the access level of one of its methods, even if a subclass overrides it with, without causing linkage errors.
Conveying intention
Access restriction is defined in JLS §6.6.1:
A member [...] of a reference type [...] is accessible only if the type is accessible and the member or constructor is declared to permit access
[...]
Otherwise, the member or constructor is declared private, and access is permitted if and only if it occurs within the body of the top level type (§7.6) that encloses the declaration of the member or constructor.
Therefore members of a private nested class can (from a source code perspective; see also "Reflection" section) only be accessed from the body of the enclosing top level type. Interestingly the "body" also covers other nested classes:
public class TopLevel {
private static class Nested1 {
private int i;
}
void doSomething(Nested1 n) {
// Can access private member of nested class
n.i++;
}
private static class Nested2 {
void doSomething(Nested1 n) {
// Can access private member of other nested class
n.i++;
}
}
}
So from a compiler-provided access restriction perspective there is indeed no point in using a public member in a private nested class.
However, using different access levels can be useful for conveying intention, especially (as pointed out by others) when the nested class might be refactored to a separate top level class in the future. Consider this example:
public class Cache {
private static class CacheEntry<T> {
private final T value;
private long lastAccessed;
// Signify that enclosing class may use this constructor
public CacheEntry(T value) {
this.value = value;
updateLastAccessed();
}
// Signify that enclosing class must NOT use this method
private void updateLastAccessed() {
lastAccessed = System.nanoTime();
}
// Signify that enclosing class may use this method
public T getValue() {
updateLastAccessed();
return value;
}
}
...
}
Compiled class files
It is also interesting to note how the Java compiler treats access to members of nested classes. Prior to JEP 181: Nest-Based Access Control (added in Java 11) the compiler had to create synthetic accessor methods because the class file could not express the access control logic related to nested classes. Consider this example:
class TopLevel {
private static class Nested {
private int i;
}
void doSomething(Nested n) {
n.i++;
}
}
When compiled with Java 8 and inspected with javap -p ./TopLevel$Nested.class you will see that a synthetic access$008 method has been added:
class TopLevel$Nested {
private int i;
private TopLevel$Nested();
static int access$008(TopLevel$Nested);
}
This slightly increased the size of the class files and might have decreased performance. This is one reason why package-private (i.e. no access modifier) access has often be chosen for members of nested classes to prevent creation of synthetic access methods.
With JEP 181 this is no longer necessary (javap -v output when compiled with JDK 11):
class TopLevel$Nested
...
{
private int i;
...
private TopLevel$Nested();
...
}
...
NestHost: class TopLevel
...
Reflection
Another interesting aspect is reflection. The JLS is sadly not verify specific in that regard, but §15.12.4.3 contains an interesting hint:
If T is in a different package than D, and their packages are in the same module, and T is public or protected, then T is accessible.
[...]
If T is protected, it is necessarily a nested type, so at compile time, its accessibility is affected by the accessibility of types enclosing its declaration. However, during linkage, its accessibility is not affected by the accessibility of types enclosing its declaration. Moreover, during linkage, a protected T is as accessible as a public T.
Similarly AccessibleObject.setAccessible(...) does not mention the enclosing type at all. And indeed it is possible to access the members of a public or protected nested type within non-public enclosing type:
test1/TopLevel1.java
package test1;
// package-private
class TopLevel1 {
private static class Nested1_1 {
protected static class Nested1_2 {
public static int i;
}
}
}
test2/TopLevel2.java
package test2;
import java.lang.reflect.Field;
public class TopLevel2 {
public static void main(String... args) throws Exception {
Class<?> nested1_2 = Class.forName("test1.TopLevel1$Nested1_1$Nested1_2");
Field f = nested1_2.getDeclaredField("i");
f.set(null, 1);
}
}
Here reflection is able to modify the field test1.TopLevel1.Nested1_1.Nested1_2.i without having to make it accessible despite it being inside a private nested class inside a package-private class.
When you are writing code for an environment where untrusted code is run you should keep that in mind to prevent malicious code from messing with internal classes.
So when it comes to the access level of nested types you should always choose the least permissive one, ideally private or package-private.
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.