This question already has answers here:
Why can't static methods be abstract in Java?
(29 answers)
Closed 3 years ago.
I want to have the family of classes which all have the same method. As this method is quite simple I want to make it final static, something like
class A {
public static final String createSth () { }
}
(in fact this method returns only String).
Sometimes it would be useful to upper-cast all those A, B, C classes with the same method. Thus I would like to create mother class.
class abstract Mother {
public static abstract String createSth () { }
}
and then to add the appropriate extends for all my classes A, B, C ex. class A extends Mother.
Unfortunately it's not allowed by Java. I'm wondering why?
Sure I can remove static final modifier and then everything is ok. But on another hand if each subclass returns the constant String which is not modifiable in any way, why not?
You can ask what is the purpose of such a construction?
Simply I want to create database sql strings. For each table I created a separate class, and as a result of createSth method I want to return sql creating a table for this class.
Interfaces does help neither.
The only solutions seems to be to remove abstract modifier from createSth method in Mother class. But then I'm not allowed to uppercast to Mother class and to call createSth method for children. So I have to remove static modifier for children classes.
Concluding why abstract method is not allowed to be static? Ok here I can even understand that, but either why non static abstract method is not allowed to be replaced by static method in child class?
static methods (just like final and private) can't be overriden so there is no way to implement them in derived class so making them abstract would not make sense.
Static methods don't get inherited, so making them abstract would be meaningless.
final methods do not get overridden
static methods do not get overridden, but they can be hidden in the subClass.
Related
Suppose I have these classes:
public class ChildClass extends ParentClass
{
// some class definition here
}
public abstract class ParentClass
{
public static void printClass()
{
// get the class that extends this one (and for example, print it)
}
// some class definition here
}
Lets say when calling ParentClass.printClass() I want to print the name of the class (like doing System.out.println(ParentClass.class)). When then extending ParentClass (for example like in ChildClass) and calling ChildClass.printClass(), I want it to print the name of the extending class (like doing System.out.println(ChildClass.class)). Is this somehow possible?
I've found a way to get the class from inside a static method by using MethodHandles.lookup().lookupClass(), but when using it inside of ParentClass.printClass and extending ParentClass, then calling printClass on the extending Class, I always get the class of ParentClass.
static methods are best thought of as living entirely outside of the class itself. The reason they do show up in classes is because of the design of java (the language) itself: Types aren't just types with a hierarchy, they also serve as the primary vehicle for java's namespacing system.
Types live in packages, packages are the top level namespace concept for types. So how do you refer to a method? There's only one way: Via the type system. Hence, static methods do have to be placed inside a type. But that's about where it ends.
They do not inherit, at all. When you write:
ChildClass.lookupClass()
The compiler just figures out: Right, well, you are clearly referring to the lookupClass() method in ParentClass so that is what I will compile. You can see this in action yourself by running javap -c -p MyExample. The same principle applies to non-static methods, even.
For instance methods, the runtime undoes this maneuvre: Whenever you invoke a method on any object, the runtime system will always perform dynamic dispatch; you can't opt out of this. You may write:
AbstractList<String> list = new ArrayList<String>();
list.sort(someComparator);
and you can use javap to verify that this will end up writing into the class file that the method AbstractList::sort is invoked. But, at runtime the JVM will always check what list is actually pointing at - it's an instance of ArrayList, not AbstractList (that's obvious: AbstractList is abstract; no object can ever be directly instantiated as `new AbstractList). If ArrayList has its own take on the sort method, then that will be called.
The key takeaway of all that is: Static methods do not inherit, therefore, this dynamic dispatch system is not available to them, therefore, what you want cannot be done in that fashion.
So what to do?
It feels like what you're doing is attempting to associate a hierarchy to properties that apply to the class itself. In other words, that you want there to be a hierarchical relationship between the notion of 'ParentClass's lookupClass method and ChildClass's lookupClass method - lookupClass is not a thing you ask an instance of ChildClass or ParentClass - you ask it at the notion of the these types themselves.
If you think about it for a moment, constructors are the same way. You don't 'ask' an instance of ArrayList for a new arraylist. You ask ArrayList, the concept. Both 'do not really do' inheritance and cannot be abstracted into a type hierarchy.
This is where factory classes come in.
Factory classes as a concept are just 'hierarchicalizing' staticness, by removing static from it: Create a sibling type to your class hierarchy (ParentClassFactory for example):
abstract class ParentClassFactory {
abstract ParentClass create();
abstract void printClass();
}
and then, in tandem with writing ChildClass, you also write ChildClassFactory. Generally factories have just one instance - you may want to employ the singleton pattern for this. Now you can do it just fine:
class ChildClassFactory extends ParentClassFactory {
private static final ChildClassFactory INSTANCE = new ChildClassFactory();
public static ChildClassFactory instance() { return INSTANCE; }
public ParentClass create() { return new ChildClass(); }
public void printClass() { System.out.println(ChildClass.class); }
}
// elsewhere:
// actually gets the ChildClassFactory singleton:
ParentClassFactory factory = ....;
factory.printClass(); // will print ChildClass!
Quoting #RealSkeptic:
Static methods are not inherited. The fact that you can call ChildClass.printClass() is just syntactic sugar. It actually always calls ParentClass.printClass(). So you can't do something like that with a static method, only an inheritable non-static one.
This question already has answers here:
When to use static methods
(24 answers)
Closed 1 year ago.
when to decide use static functions.
when my function only called inside the same class is there is any need to make it static ?
as search I cant find full clear declaration
Static methods or variables are not part of just one Object, They are part of all instances of same type as declaring class.
When you declare a function as static in a class, for example we have class Animal and this class will have a function that can be called without creating an Object out of this class. Let's say that the function is called roar()
If we declare it this way:
public void roar() {...}
To use it we would have to do the following steps:
Animal.roar() // It won't work!!!❌
Animal a = new Animal();
a.roar(); // Works ✔
If we declare it with the static keyword:
public static void roar() {...}
Then we are able to do this:
Animal.roar(); // We call the function directly from the class, without creating an Object
Regarding your last question, you do not need to make a function static to call it from within a class. You can but you don't need to.
If your function is being called only inside, there is no need to declare it static, you could even declare it as private to abstract the user from the inner implementation.
Let me break down static functions, I also had a hard time understanding at the beginning.
For example, we have a
public static void main(String[] args) {}
It basically tells the JVM (Java Virtual Machine) that it can and should invoke this method on the start up of the program. However, it is declared as static so that JVM can call this method without instantiating the main class.
So think of static methods as something that is not bound to a specific object, it can be also variable (maybe even a constant) that is shared among the instances of that class.
I usually declare static methods for utility purposes.
Note: static variables and functions can be invoked in non static methods, however, the other way it will not work.
Hope I helped you :)
I was going through a part of a code which was something like this
// compare points according to their polar radius
public static final Comparator<Point2D> R_ORDER = new ROrder();
.
.
.
private static class ROrder implements Comparator<Point2D> {
public int compare(Point2D p, Point2D q) {
double delta = (p.x*p.x + p.y*p.y) - (q.x*q.x + q.y*q.y);
if (delta < 0) return -1;
if (delta > 0) return +1;
return 0;
}
}
Why do we have such public methods inside private static classes. What harm would it do if i made ROrder
Non-Static
Public
ROrder Non-Static
By making it non-static you will need the instance of the container class to create the instance of ROder, which maybe due to the design of the class would not make logic. You should keep class non-static only when you really need the instance of outer class to get the instance of inner class.
ROrder Public
Again because they wanted to restrict the use of ROrder outside the context of this class. They did not want any client code or other code to freely create instances of ROrder, as they would not be of any use.
Why do we have such public methods inside private static classes.
In this case because you are implementing an interface Comparator and you will pass this comparator for other uses, such as sorting and you would want the Collections class to have the visibility of compare method, so the method has to be public even if the class implementing the interface is private.
So this is just a logical way to enhance the readability and intent of use of the code.
Logical Use
This class wants the string to be in some format.
public class SomeClass{
private static class StringHelper{
//will do the task of parsing and validating that string object
}
}
Now in this case you would not want to keep StringHelper class public, as its use is too localized to be reused. So you would rather emphasize that by keeping it private. And there can be methods that are public if StringHelper implemented some interface.
UPDATE:
You should keep class non-static only when you really need the
instance of outer class to get the instance of inner class.
On that I think the answer can be too broad, but I would try to explain in short. By that what I mean was that if the inner class object shares some state of the outer object on which its processing is dependent, then you will need the object of outer class to share its state with the inner class object, but if the inner class instance is independent of the state of outer class, then it is safe to keep the inner class static.
This class implements Comparator and so must implement its methods. The implementation methods can't be static. Also, since interface methods are implicitly public, they must be declared public, regardless of the containing class's visibility. Try not doing so and it will fail to compile. This is certainly the reason it is declared public here -- it can't not be.
This is true regardless of whether the containing class is static or public. Here, it could be either of those things and the method inside would still have to be public and non-static.
Other methods that don't implement an interface could be private, and, logically probably should inside a private class as there would be no point in declaring it otherwise -- but it would be allowed by Java syntax.
All private members (fields, classes, whatever) are only visible inside the class. So, it doesn't matter what visibility you give a method of a private class - all methods will only be visible inside the containing class, because the class itself is private.
If the inner class implements an interface or extends a class, overridden methods may not have less visibility than the declaration in the super type, so that's one reason to have public methods in a private inner class.
However, although the syntax allows private classes to have public methods, it won't increase the visibility of those methods sufficiently to be visible outside the containing class. There are several examples in java of modifiers being legal but having no effect, such as inner interfaces being implicitly static (whether or not the static keyword is used).
This class is private because developer did not want to ROrder be instantiated in other place. But an instance can be accessed through the constant R_ORDER from other classes.
The method is public for two reason : first, compare is defined in the Comparator interface. Second, as R_ORDER is accessible from other classes, it is more than convenient to be able to call a method on this object. In this case, it is compare.
Finally, if the class was not static, it would keep a reference to the parent class, which is almost always not needed
I have an abstract class A
I have about 10 classes that extend A
Class A has one or two static methods and it makes sense that these are static, because they belong to the 10 classes, NOT instances of them. One static method e.g. is called getAllFromX, which gets all all instances of the class from X, whatever that may be, it may be a server, well it actually is, but it doesn't matter. So you see it makes sense these methods are static and are not bound to an instance.
At the same time class A has a NON-static abstract method, each subclass overrides this method (just returns a string). I cannot make it static because static methods cannot be overridden (...).
To summarize: abstract class A has a static method and a abstract non-static method, that is overriden by the subclasses. I cannot make the second method static because it must be overriden. On the otherhand I could make the first method non-static, but it would be very ugly and bad programming style, so I'll leave it that way.
The catch? The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Is the "easiest" way to use reflection to get this done? I mean...really?
Like e.g., I get the class the static method is in:
Class<?> cl=new Object(){}.getClass().getEnclosingClass(); (a hack I found here, thank god...)
I then use getConstructor to construct an object of this subclass.
And then I use this object to call the non-static method.
Really?? Can it not be done easier? I mean that is if I want to design my program conceptually correct...
Coming from C# I don't like that (and the type erasure thing). It is just ugly. Doable but ugly. And a big stumbling block, at least for beginners. EDIT: after reading it again, I'd add: /rant end. Sorry, but I actually care.
I think what you in fact need is the following:
public class A {
public static Set<A> getAllFromX() {
...
}
}
public class B extends A {
public static Set<B> getAllFromX() {
...
}
}
public class C extends A {
public static Set<C> getAllFromX() {
...
}
}
(Just as the valueOf() and values() methods in enums, which is redefined in every Enum subclass, because static methods can't be inherited)
In this case, each class has its own static method doing whatever it wants. But your question doesn't make much sense because it says:
The static method in class A must get the value the non-static method returns (for the subclass the static method is inherited from, of course).
Indeed, the static method is not inherited by the subclass. Static methods are never inherited. If you define a static method foo() in A, and call
B.foo();
the compiler doesn't refuse to compile it, but it translates it to
A.foo();
So, there's no way to do in foo() something that depends on the class on which foo() is called, since it's always A.
You can always use reflection to invoke a method using class name e.g.
Object objectX = ClassX.class.newInstance();
//get your method passing argument types as second param
Method method = ClassX.class.getDeclaredMethod("methodX", null);
//invoke your method passing arguments as second param
method.invoke(objectX, null);
Since you mentioned your static method doesn't use any instance but you are using reflection to get the instance hence I am really not sure, how does it fit in your requirement though.
I think making it as an implemented method (non-static) in your abstract class is a better choice. That way you implement it once but its available in in all your 10 extending classes.
I think your problem is one of larger design. A different object should be responsible for retrieving instances of A or its subclasses. As you can see, relying on a static method to be replaced by subclasses does not work well. Without knowing more about the problem domain, it's hard to give a good answer, but I would consider something similar to the Abstract Factory pattern.
Broadly speaking: Define an abstract class, AFactory, with a method Collection getInstances(). Extend AFactory for each of the concrete subclasses of A you need to return and implement that logic in the overridden getInstances() method as appropriate. You may also provide a static method on the abstract AFactory, getFactory(Class), to get the appropriate factory subtype at runtime.
This question already has answers here:
Why can't I define a static method in a Java interface?
(24 answers)
Closed 3 years ago.
There have been a few questions asked here about why you can't define static methods within interfaces, but none of them address a basic inconsistency: why can you define static fields and static inner types within an interface, but not static methods?
Static inner types perhaps aren't a fair comparison, since that's just syntactic sugar that generates a new class, but why fields but not methods?
An argument against static methods within interfaces is that it breaks the virtual table resolution strategy used by the JVM, but shouldn't that apply equally to static fields, i.e. the compiler can just inline it?
Consistency is what I desire, and Java should have either supported no statics of any form within an interface, or it should be consistent and allow them.
An official proposal has been made to allow static methods in interfaces in Java 7. This proposal is being made under Project Coin.
My personal opinion is that it's a great idea. There is no technical difficulty in implementation, and it's a very logical, reasonable thing to do. There are several proposals in Project Coin that I hope will never become part of the Java language, but this is one that could clean up a lot of APIs. For example, the Collections class has static methods for manipulating any List implementation; those could be included in the List interface.
Update: In the Java Posse Podcast #234, Joe D'arcy mentioned the proposal briefly, saying that it was "complex" and probably would not make it in under Project Coin.
Update: While they didn't make it into Project Coin for Java 7, Java 8 does support static functions in interfaces.
I'm going to go with my pet theory with this one, which is that the lack of consistency in this case is a matter of convenience rather than design or necessity, since I've heard no convincing argument that it was either of those two.
Static fields are there (a) because they were there in JDK 1.0, and many dodgy decisions were made in JDK 1.0, and (b) static final fields in interfaces are the closest thing java had to constants at the time.
Static inner classes in interfaces were allowed because that's pure syntactic sugar - the inner class isn't actually anything to do with the parent class.
So static methods aren't allowed simply because there's no compelling reason to do so; consistency isn't sufficiently compelling to change the status quo.
Of course, this could be permitted in future JLS versions without breaking anything.
There is never a point to declaring a static method in an interface. They cannot be executed by the normal call MyInterface.staticMethod(). (EDIT:Since that last sentence confused some people, calling MyClass.staticMethod() executes precisely the implementation of staticMethod on MyClass, which if MyClass is an interface cannot exist!) If you call them by specifying the implementing class MyImplementor.staticMethod() then you must know the actual class, so it is irrelevant whether the interface contains it or not.
More importantly, static methods are never overridden, and if you try to do:
MyInterface var = new MyImplementingClass();
var.staticMethod();
the rules for static say that the method defined in the declared type of var must be executed. Since this is an interface, this is impossible.
You can of course always remove the static keyword from the method. Everything will work fine. You may have to suppress some warnings if it is called from an instance method.
To answer some of the comments below, the reason you can't execute "result=MyInterface.staticMethod()" is that it would have to execute the version of the method defined in MyInterface. But there can't be a version defined in MyInterface, because it's an interface. It doesn't have code by definition.
The purpose of interfaces is to define a contract without providing an implementation. Therefore, you can't have static methods, because they'd have to have an implementation already in the interface since you can't override static methods. As to fields, only static final fields are allowed, which are, essentially, constants (in 1.5+ you can also have enums in interfaces). The constants are there to help define the interface without magic numbers.
BTW, there's no need to explicitly specify static final modifiers for fields in interfaces, because only static final fields are allowed.
This is an old thread , but this is something very important question for all. Since i noticed this today only so i am trying to explain it in cleaner way:
The main purpose of interface is to provide something that is unimplementable, so if they provide
static methods to be allowed
then you can call that method using interfaceName.staticMethodName(), but this is unimplemented method and contains nothing. So it is useless to allow static methods. Therefore they do not provide this at all.
static fields are allowed
because fields are not implementable, by implementable i mean you can not perform any logical operation in field, you can do operation on field. So you are not changing behavior of field that is why they are allowed.
Inner classes are allowed
Inner classes are allowed because after compilation different class file of the Inner class is created say InterfaceName$InnerClassName.class , so basically you are providing implementation in different entity all together but not in interface. So implementation in Inner classes is provided.
I hope this would help.
Actually sometimes there are reasons someone can benefit from static methods. They can be used as factory methods for the classes that implement the interface. For example that's the reason we have Collection interface and the Collections class in openjdk now. So there are workarounds as always - provide another class with a private constructor which will serve as a "namespace" for the static methods.
Prior to Java 5, a common usage for static fields was:
interface HtmlConstants {
static String OPEN = "<";
static String SLASH_OPEN = "</";
static String CLOSE = ">";
static String SLASH_CLOSE = " />";
static String HTML = "html";
static String BODY = "body";
...
}
public class HtmlBuilder implements HtmlConstants { // implements ?!?
public String buildHtml() {
StringBuffer sb = new StringBuffer();
sb.append(OPEN).append(HTML).append(CLOSE);
sb.append(OPEN).append(BODY).append(CLOSE);
...
sb.append(SLASH_OPEN).append(BODY).append(CLOSE);
sb.append(SLASH_OPEN).append(HTML).append(CLOSE);
return sb.toString();
}
}
This meant HtmlBuilder would not have to qualify each constant, so it could use OPEN instead of HtmlConstants.OPEN
Using implements in this way is ultimately confusing.
Now with Java 5, we have the import static syntax to achieve the same effect:
private final class HtmlConstants {
...
private HtmlConstants() { /* empty */ }
}
import static HtmlConstants.*;
public class HtmlBuilder { // no longer uses implements
...
}
There is no real reason for not having static methods in interfaces except: the Java language designers did not want it like that.
From a technical standpoint it would make sense to allow them. After all an abstract class can have them as well. I assume but did not test it, that you can "hand craft" byte code where the interface has a static method and it should imho work with no problems to call the method and/or to use the interface as usually.
I often wonder why static methods at all? They do have their uses, but package/namespace level methods would probably cover 80 of what static methods are used for.
Two main reasons spring to mind:
Static methods in Java cannot be overridden by subclasses, and this is a much bigger deal for methods than static fields. In practice, I've never even wanted to override a field in a subclass, but I override methods all the time. So having static methods prevents a class implementing the interface from supplying its own implementation of that method, which largely defeats the purpose of using an interface.
Interfaces aren't supposed to have code; that's what abstract classes are for. The whole point of an interface is to let you talk about possibly-unrelated objects which happen to all have a certain set of methods. Actually providing an implementation of those methods is outside the bounds of what interfaces are intended to be.
Static methods are tied to a class. In Java, an interface is not technically a class, it is a type, but not a class (hence, the keyword implements, and interfaces do not extend Object). Because interfaces are not classes, they cannot have static methods, because there is no actual class to attach to.
You may call InterfaceName.class to get the Class Object corresponding to the interface, but the Class class specifically states that it represents classes and interfaces in a Java application. However, the interface itself is not treated as a class, and hence you cannot attach a static method.
Only static final fields may be declared in an interface (much like methods, which are public even if you don't include the "public" keyword, static fields are "final" with or without the keyword).
These are only values, and will be copied literally wherever they are used at compile time, so you never actually "call" static fields at runtime. Having a static method would not have the same semantics, since it would involve calling an interface without an implementation, which Java does not allow.
The reason is that all methods defined in an interface are abstract whether or not you explicitly declare that modifier. An abstract static method is not an allowable combination of modifiers since static methods are not able to be overridden.
As to why interfaces allow static fields. I have a feeling that should be considered a "feature". The only possibility I can think of would be to group constants that implementations of the interface would be interested in.
I agree that consistency would have been a better approach. No static members should be allowed in an interface.
I believe that static methods can be accessed without creating an object and the interface does not allow creating an object as to restrict the programmers from using the interface methods directly rather than from its implemented class.
But if you define a static method in an interface, you can access it directly without its implementation. Thus static methods are not allowed in interfaces.
I don't think that consistency should be a concern.
Java 1.8 interface static method is visible to interface methods only, if we remove the methodSta1() method from the InterfaceExample class,
we won’t be able to use it for the InterfaceExample object. However like other static methods, we can use interface static methods using class name.
For example, a valid statement will be:
exp1.methodSta1();
So after looking below example we can say :
1) Java interface static method is part of interface, we can’t use it for implementation class objects.
2) Java interface static methods are good for providing utility methods, for example null check, collection sorting ,log etc.
3) Java interface static method helps us in providing security by not allowing implementation classes (InterfaceExample) to override them.
4) We can’t define interface static method for Object class methods, we will get compiler error as “This static method cannot hide the instance method from Object”. This is because it’s not allowed in java, since Object is the base class for all the classes and we can’t have one class level static method and another instance method with same signature.
5) We can use java interface static methods to remove utility classes such as Collections and move all of it’s static methods to the corresponding interface,
that would be easy to find and use.
public class InterfaceExample implements exp1 {
#Override
public void method() {
System.out.println("From method()");
}
public static void main(String[] args) {
new InterfaceExample().method2();
InterfaceExample.methodSta2(); // <--------------------------- would not compile
// methodSta1(); // <--------------------------- would not compile
exp1.methodSta1();
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= InterfaceExample :: from methodSta2() ======");
}
}
interface exp1 {
void method();
//protected void method1(); // <-- error
//private void method2(); // <-- error
//static void methodSta1(); // <-- error it require body in java 1.8
static void methodSta1() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta1() ======");
}
static void methodSta2() { // <-- it compile successfully but it can't be overridden in child classes
System.out.println("========= exp1:: from methodSta2() ======");
}
default void method2() { System.out.println("--- exp1:: from method2() ---");}
//synchronized default void method3() { System.out.println("---");} // <-- Illegal modifier for the interface method method3; only public, abstract, default, static
// and strictfp are permitted
//final default void method3() { System.out.println("---");} // <-- error
}