Related
Why is it not possible to override static methods?
If possible, please use an example.
Overriding depends on having an instance of a class. The point of polymorphism is that you can subclass a class and the objects implementing those subclasses will have different behaviors for the same methods defined in the superclass (and overridden in the subclasses). A static method is not associated with any instance of a class so the concept is not applicable.
There were two considerations driving Java's design that impacted this. One was a concern with performance: there had been a lot of criticism of Smalltalk about it being too slow (garbage collection and polymorphic calls being part of that) and Java's creators were determined to avoid that. Another was the decision that the target audience for Java was C++ developers. Making static methods work the way they do had the benefit of familiarity for C++ programmers and was also very fast, because there's no need to wait until runtime to figure out which method to call.
Personally I think this is a flaw in the design of Java. Yes, yes, I understand that non-static methods are attached to an instance while static methods are attached to a class, etc etc. Still, consider the following code:
public class RegularEmployee {
private BigDecimal salary;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(getBonusMultiplier());
}
/* ... presumably lots of other code ... */
}
public class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
This code will not work as you might expect. Namely, SpecialEmployee's get a 2% bonus just like regular employees. But if you remove the "static"s, then SpecialEmployee's get a 3% bonus.
(Admittedly, this example is poor coding style in that in real life you would likely want the bonus multiplier to be in a database somewhere rather than hard-coded. But that's just because I didn't want to bog down the example with a lot of code irrelevant to the point.)
It seems quite plausible to me that you might want to make getBonusMultiplier static. Perhaps you want to be able to display the bonus multiplier for all the categories of employees, without needing to have an instance of an employee in each category. What would be the point of searching for such example instances? What if we are creating a new category of employee and don't have any employees assigned to it yet? This is quite logically a static function.
But it doesn't work.
And yes, yes, I can think of any number of ways to rewrite the above code to make it work. My point is not that it creates an unsolvable problem, but that it creates a trap for the unwary programmer, because the language does not behave as I think a reasonable person would expect.
Perhaps if I tried to write a compiler for an OOP language, I would quickly see why implementing it so that static functions can be overriden would be difficult or impossible.
Or perhaps there is some good reason why Java behaves this way. Can anyone point out an advantage to this behavior, some category of problem that is made easier by this? I mean, don't just point me to the Java language spec and say "see, this is documented how it behaves". I know that. But is there a good reason why it SHOULD behave this way? (Besides the obvious "making it work right was too hard"...)
Update
#VicKirk: If you mean that this is "bad design" because it doesn't fit how Java handles statics, my reply is, "Well, duh, of course." As I said in my original post, it doesn't work. But if you mean that it is bad design in the sense that there would be something fundamentally wrong with a language where this worked, i.e. where statics could be overridden just like virtual functions, that this would somehow introduce an ambiguity or it would be impossible to implement efficiently or some such, I reply, "Why? What's wrong with the concept?"
I think the example I give is a very natural thing to want to do. I have a class that has a function that does not depend on any instance data, and which I might very reasonably want to call independent of an instance, as well as wanting to call from within an instance method. Why should this not work? I've run into this situation a fair number of times over the years. In practice I get around it by making the function virtual, and then creating a static method whose only purpose in life is to be a static method that passes the call on to the virtual method with a dummy instance. That seems like a very roundabout way to get there.
The short answer is: it is entirely possible, but Java doesn't do it.
Here is some code which illustrates the current state of affairs in Java:
File Base.java:
package sp.trial;
public class Base {
static void printValue() {
System.out.println(" Called static Base method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Base method.");
}
void nonLocalIndirectStatMethod() {
System.out.println(" Non-static calls overridden(?) static:");
System.out.print(" ");
this.printValue();
}
}
File Child.java:
package sp.trial;
public class Child extends Base {
static void printValue() {
System.out.println(" Called static Child method.");
}
void nonStatPrintValue() {
System.out.println(" Called non-static Child method.");
}
void localIndirectStatMethod() {
System.out.println(" Non-static calls own static:");
System.out.print(" ");
printValue();
}
public static void main(String[] args) {
System.out.println("Object: static type Base; runtime type Child:");
Base base = new Child();
base.printValue();
base.nonStatPrintValue();
System.out.println("Object: static type Child; runtime type Child:");
Child child = new Child();
child.printValue();
child.nonStatPrintValue();
System.out.println("Class: Child static call:");
Child.printValue();
System.out.println("Class: Base static call:");
Base.printValue();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Child:");
child.localIndirectStatMethod();
System.out.println("Object: static/runtime type Child -- call static from non-static method of Base:");
child.nonLocalIndirectStatMethod();
}
}
If you run this (I did it on a Mac, from Eclipse, using Java 1.6) you get:
Object: static type Base; runtime type Child.
Called static Base method.
Called non-static Child method.
Object: static type Child; runtime type Child.
Called static Child method.
Called non-static Child method.
Class: Child static call.
Called static Child method.
Class: Base static call.
Called static Base method.
Object: static/runtime type Child -- call static from non-static method of Child.
Non-static calls own static.
Called static Child method.
Object: static/runtime type Child -- call static from non-static method of Base.
Non-static calls overridden(?) static.
Called static Base method.
Here, the only cases which might be a surprise (and which the question is about) appear to be the first case:
"The run-time type is not used to determine which static methods are called, even when called with an object instance (obj.staticMethod())."
and the last case:
"When calling a static method from within an object method of a class, the static method chosen is the one accessible from the class itself and not from the class defining the run-time type of the object."
Calling with an object instance
The static call is resolved at compile-time, whereas a non-static method call is resolved at run-time. Notice that although static methods are inherited (from parent) they are not overridden (by child). This could be a surprise if you expected otherwise.
Calling from within an object method
Object method calls are resolved using the run-time type, but static (class) method calls are resolved using the compile-time (declared) type.
Changing the rules
To change these rules, so that the last call in the example called Child.printValue(), static calls would have to be provided with a type at run-time, rather than the compiler resolving the call at compile-time with the declared class of the object (or context). Static calls could then use the (dynamic) type hierarchy to resolve the call, just as object method calls do today.
This would easily be doable (if we changed Java :-O), and is not at all unreasonable, however, it has some interesting considerations.
The main consideration is that we need to decide which static method calls should do this.
At the moment, Java has this "quirk" in the language whereby obj.staticMethod() calls are replaced by ObjectClass.staticMethod() calls (normally with a warning). [Note: ObjectClass is the compile-time type of obj.] These would be good candidates for overriding in this way, taking the run-time type of obj.
If we did it would make method bodies harder to read: static calls in a parent class could potentially be dynamically "re-routed". To avoid this we would have to call the static method with a class name -- and this makes the calls more obviously resolved with the compile-time type hierarchy (as now).
The other ways of invoking a static method are more tricky: this.staticMethod() should mean the same as obj.staticMethod(), taking the run-time type of this. However, this might cause some headaches with existing programs, which call (apparently local) static methods without decoration (which is arguably equivalent to this.method()).
So what about unadorned calls staticMethod()? I suggest they do the same as today, and use the local class context to decide what to do. Otherwise great confusion would ensue. Of course it means that method() would mean this.method() if method was a non-static method, and ThisClass.method() if method were a static method. This is another source of confusion.
Other considerations
If we changed this behaviour (and made static calls potentially dynamically non-local), we would probably want to revisit the meaning of final, private and protected as qualifiers on static methods of a class. We would then all have to get used to the fact that private static and public final methods are not overridden, and can therefore be safely resolved at compile-time, and are "safe" to read as local references.
Actually we were wrong.
Despite Java doesn't allow you to override static methods by default, if you look thoroughly through documentation of Class and Method classes in Java, you can still find a way to emulate static methods overriding by following workaround:
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
class RegularEmployee {
private BigDecimal salary = BigDecimal.ONE;
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".02");
}
public BigDecimal calculateBonus() {
return salary.multiply(this.getBonusMultiplier());
}
public BigDecimal calculateOverridenBonus() {
try {
// System.out.println(this.getClass().getDeclaredMethod(
// "getBonusMultiplier").toString());
try {
return salary.multiply((BigDecimal) this.getClass()
.getDeclaredMethod("getBonusMultiplier").invoke(this));
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
// ... presumably lots of other code ...
}
final class SpecialEmployee extends RegularEmployee {
public static BigDecimal getBonusMultiplier() {
return new BigDecimal(".03");
}
}
public class StaticTestCoolMain {
static public void main(String[] args) {
RegularEmployee Alan = new RegularEmployee();
System.out.println(Alan.calculateBonus());
System.out.println(Alan.calculateOverridenBonus());
SpecialEmployee Bob = new SpecialEmployee();
System.out.println(Bob.calculateBonus());
System.out.println(Bob.calculateOverridenBonus());
}
}
Resulting output:
0.02
0.02
0.02
0.03
what we were trying to achieve :)
Even if we declare third variable Carl as RegularEmployee and assign to it instance of SpecialEmployee, we will still have call of RegularEmployee method in first case and call of SpecialEmployee method in second case
RegularEmployee Carl = new SpecialEmployee();
System.out.println(Carl.calculateBonus());
System.out.println(Carl.calculateOverridenBonus());
just look at output console:
0.02
0.03
;)
Static methods are treated as global by the JVM, there are not bound to an object instance at all.
It could conceptually be possible if you could call static methods from class objects (like in languages like Smalltalk) but it's not the case in Java.
EDIT
You can overload static method, that's ok. But you can not override a static method, because class are no first-class object. You can use reflection to get the class of an object at run-time, but the object that you get does not parallel the class hierarchy.
class MyClass { ... }
class MySubClass extends MyClass { ... }
MyClass obj1 = new MyClass();
MySubClass obj2 = new MySubClass();
ob2 instanceof MyClass --> true
Class clazz1 = obj1.getClass();
Class clazz2 = obj2.getClass();
clazz2 instanceof clazz1 --> false
You can reflect over the classes, but it stops there. You don't invoke a static method by using clazz1.staticMethod(), but using MyClass.staticMethod(). A static method is not bound to an object and there is hence no notion of this nor super in a static method. A static method is a global function; as a consequence there is also no notion of polymorphism and, therefore, method overriding makes no sense.
But this could be possible if MyClass was an object at run-time on which you invoke a method, as in Smalltalk (or maybe JRuby as one comment suggest, but I know nothing of JRuby).
Oh yeah... one more thing. You can invoke a static method through an object obj1.staticMethod() but that really syntactic sugar for MyClass.staticMethod() and should be avoided. It usually raises a warning in modern IDE. I don't know why they ever allowed this shortcut.
Method overriding is made possible by dynamic dispatching, meaning that the declared type of an object doesn't determine its behavior, but rather its runtime type:
Animal lassie = new Dog();
lassie.speak(); // outputs "woof!"
Animal kermit = new Frog();
kermit.speak(); // outputs "ribbit!"
Even though both lassie and kermit are declared as objects of type Animal, their behavior (method .speak()) varies because dynamic dispatching will only bind the method call .speak() to an implementation at run time - not at compile time.
Now, here's where the static keyword starts to make sense: the word "static" is an antonym for "dynamic". So the reason why you can't override static methods is because there is no dynamic dispatching on static members - because static literally means "not dynamic". If they dispatched dynamically (and thus could be overriden) the static keyword just wouldn't make sense anymore.
Yes. Practically Java allows overriding static method, and No theoretically if you Override a static method in Java then it will compile and run smoothly but it will lose Polymorphism which is the basic property of Java. You will Read Everywhere that it is not possible to try yourself compiling and running. you will get your answer. e.g. If you Have Class Animal and a static method eat() and you Override that static method in its Subclass lets called it Dog. Then when wherever you Assign a Dog object to an Animal Reference and call eat() according to Java Dog's eat() should have been called but in static Overriding Animals' eat() will Be Called.
class Animal {
public static void eat() {
System.out.println("Animal Eating");
}
}
class Dog extends Animal{
public static void eat() {
System.out.println("Dog Eating");
}
}
class Test {
public static void main(String args[]) {
Animal obj= new Dog();//Dog object in animal
obj.eat(); //should call dog's eat but it didn't
}
}
Output Animal Eating
According to Polymorphism Principle of Java, the Output Should be Dog Eating.
But the result was different because to support Polymorphism Java uses Late Binding that means methods are called only at the run-time but not in the case of static methods. In static methods compiler calls methods at the compile time rather than the run-time, so we get methods according to the reference and not according to the object a reference a containing that's why You can say Practically it supports static overring but theoretically, it doesn't.
In Java (and many OOP languages, but I cannot speak for all; and some do not have static at all) all methods have a fixed signature - the parameters and types. In a virtual method, the first parameter is implied: a reference to the object itself and when called from within the object, the compiler automatically adds this.
There is no difference for static methods - they still have a fixed signature. However, by declaring the method static you have explicitly stated that the compiler must not include the implied object parameter at the beginning of that signature. Therefore, any other code that calls this must must not attempt to put a reference to an object on the stack. If it did do that, then the method execution would not work since the parameters would be in the wrong place - shifted by one - on the stack.
Because of this difference between the two; virtual methods always have a reference to the context object (i.e. this) so then it is possible to reference anything within the heap that belong to that instance of the object. But with static methods, since there is no reference passed, that method cannot access any object variables and methods since the context is not known.
If you wish that Java would change the definition so that a object context is passed in for every method, static or virtual, then you would in essence have only virtual methods.
As someone asked in a comment to the op - what is your reason and purpose for wanting this feature?
I do not know Ruby much, as this was mentioned by the OP, I did some research. I see that in Ruby classes are really a special kind of object and one can create (even dynamically) new methods. Classes are full class objects in Ruby, they are not in Java. This is just something you will have to accept when working with Java (or C#). These are not dynamic languages, though C# is adding some forms of dynamic. In reality, Ruby does not have "static" methods as far as I could find - in that case these are methods on the singleton class object. You can then override this singleton with a new class and the methods in the previous class object will call those defined in the new class (correct?). So if you called a method in the context of the original class it still would only execute the original statics, but calling a method in the derived class, would call methods either from the parent or sub-class. Interesting and I can see some value in that. It takes a different thought pattern.
Since you are working in Java, you will need to adjust to that way of doing things. Why they did this? Well, probably to improve performance at the time based on the technology and understanding that was available. Computer languages are constantly evolving. Go back far enough and there is no such thing as OOP. In the future, there will be other new ideas.
EDIT: One other comment. Now that I see the differences and as I Java/C# developer myself, I can understand why the answers you get from Java developers may be confusing if you are coming from a language like Ruby. Java static methods are not the same as Ruby class methods. Java developers will have a hard time understanding this, as will conversely those who work mostly with a language like Ruby/Smalltalk. I can see how this would also be greatly confusing by the fact that Java also uses "class method" as another way to talk about static methods but this same term is used differently by Ruby. Java does not have Ruby style class methods (sorry); Ruby does not have Java style static methods which are really just old procedural style functions, as found in C.
By the way - thanks for the question! I learned something new for me today about class methods (Ruby style).
Well... the answer is NO if you think from the perspective of how an overriden method should behave in Java. But, you don't get any compiler error if you try to override a static method. That means, if you try to override, Java doesn't stop you doing that; but you certainly don't get the same effect as you get for non-static methods. Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it (which is the case with overriden static methods). Okay... any guesses for the reason why do they behave strangely? Because they are class methods and hence access to them is always resolved during compile time only using the compile time type information. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it :-)
Example: let's try to see what happens if we try overriding a static method:-
class SuperClass {
// ......
public static void staticMethod() {
System.out.println("SuperClass: inside staticMethod");
}
// ......
}
public class SubClass extends SuperClass {
// ......
// overriding the static method
public static void staticMethod() {
System.out.println("SubClass: inside staticMethod");
}
// ......
public static void main(String[] args) {
// ......
SuperClass superClassWithSuperCons = new SuperClass();
SuperClass superClassWithSubCons = new SubClass();
SubClass subClassWithSubCons = new SubClass();
superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
// ...
}
}
Output:-
SuperClass: inside staticMethod
SuperClass: inside staticMethod
SubClass: inside staticMethod
Notice the second line of the output. Had the staticMethod been overriden this line should have been identical to the third line as we're invoking the 'staticMethod()' on an object of Runtime Type as 'SubClass' and not as 'SuperClass'. This confirms that the static methods are always resolved using their compile time type information only.
I like and double Jay's comment (https://stackoverflow.com/a/2223803/1517187).
I agree that this is the bad design of Java.
Many other languages support overriding static methods, as we see in previous comments.
I feel Jay has also come to Java from Delphi like me.
Delphi (Object Pascal) was one of the languages implementing OOP before Java and one of the first languages used for commercial application development.
It is obvious that many people had experience with that language since it was in the past the only language to write commercial GUI products. And - yes, we could in Delphi override static methods. Actually, static methods in Delphi are called "class methods", while Delphi had the different concept of "Delphi static methods" which were methods with early binding. To override methods you had to use late binding, declare "virtual" directive. So it was very convenient and intuitive and I would expect this in Java.
In general it doesn't make sense to allow 'overriding' of static methods as there would be no good way to determine which one to call at runtime. Taking the Employee example, if we call RegularEmployee.getBonusMultiplier() - which method is supposed to be executed?
In the case of Java, one could imagine a language definition where it is possible to 'override' static methods as long as they are called through an object instance. However, all this would do is to re-implement regular class methods, adding redundancy to the language without really adding any benefit.
overriding is reserved for instance members to support polymorphic behaviour. static class members do not belong to a particular instance. instead, static members belong to the class and as a result overriding is not supported because subclasses only inherit protected and public instance members and not static members. You may want to define an inerface and research factory and/or strategy design patterns to evaluate an alternate approach.
By overriding we can create a polymorphic nature depending on the object type. Static method has no relation with object. So java can not support static method overriding.
By overriding, you achieve dynamic polymorphism.
When you say overriding static methods, the words you are trying to use are contradictory.
Static says - compile time, overriding is used for dynamic polymorphism.
Both are opposite in nature, and hence can't be used together.
Dynamic polymorphic behavior comes when a programmer uses an object and accessing an instance method. JRE will map different instance methods of different classes based on what kind of object you are using.
When you say overriding static methods, static methods we will access by using the class name, which will be linked at compile time, so there is no concept of linking methods at runtime with static methods. So the term "overriding" static methods itself doesn't make any meaning.
Note: even if you access a class method with an object, still java compiler is intelligent enough to find it out, and will do static linking.
Overriding in Java simply means that the particular method would be called based on the runtime type
of the object and not on the compile-time type of it (which is the case with overridden static methods). As static methods are class methods they are not instance methods so they have nothing to do with the fact which reference is pointing to which Object or instance, because due to the nature of static method it belongs to a specific class. You can redeclare it in the subclass but that subclass won't know anything about the parent class' static methods because, as I said, it is specific to only that class in which it has been declared. Accessing them using object references is just an extra liberty given by the designers of Java and we should certainly not think of stopping that practice only when they restrict it
more details and example
http://faisalbhagat.blogspot.com/2014/09/method-overriding-and-method-hiding.html
What good will it do to override static methods. You cannot call static methods through an instance.
MyClass.static1()
MySubClass.static1() // If you overrode, you have to call it through MySubClass anyway.
EDIT : It appears that through an unfortunate oversight in language design, you can call static methods through an instance. Generally nobody does that. My bad.
Answer of this question is simple, the method or variable marked as static belongs to the class only, So that static method cannot be inherited in the sub class because they belong to the super class only.
Easy solution: Use singleton instance. It will allow overrides and inheritance.
In my system, I have SingletonsRegistry class, which returns instance for passed Class. If instance is not found, it is created.
Haxe language class:
package rflib.common.utils;
import haxe.ds.ObjectMap;
class SingletonsRegistry
{
public static var instances:Map<Class<Dynamic>, Dynamic>;
static function __init__()
{
StaticsInitializer.addCallback(SingletonsRegistry, function()
{
instances = null;
});
}
public static function getInstance(cls:Class<Dynamic>, ?args:Array<Dynamic>)
{
if (instances == null) {
instances = untyped new ObjectMap<Dynamic, Dynamic>();
}
if (!instances.exists(cls))
{
if (args == null) args = [];
instances.set(cls, Type.createInstance(cls, args));
}
return instances.get(cls);
}
public static function validate(inst:Dynamic, cls:Class<Dynamic>)
{
if (instances == null) return;
var inst2 = instances[cls];
if (inst2 != null && inst != inst2) throw "Can\'t create multiple instances of " + Type.getClassName(cls) + " - it's singleton!";
}
}
A Static method, variable, block or nested class belongs to the entire class rather than an object.
A Method in Java is used to expose the behaviour of an Object / Class. Here, as the method is static (i.e, static method is used to represent the behaviour of a class only.) changing/ overriding the behaviour of entire class will violate the phenomenon of one of the fundamental pillar of Object oriented programming i.e, high cohesion. (remember a constructor is a special kind of method in Java.)
High Cohesion - One class should have only one role. For example: A car class should produce only car objects and not bike, trucks, planes etc. But the Car class may have some features(behaviour) that belongs to itself only.
Therefore, while designing the java programming language. The language designers thought to allow developers to keep some behaviours of a class to itself only by making a method static in nature.
The below piece code tries to override the static method, but will not encounter any compilation error.
public class Vehicle {
static int VIN;
public static int getVehileNumber() {
return VIN;
}}
class Car extends Vehicle {
static int carNumber;
public static int getVehileNumber() {
return carNumber;
}}
This is because, here we are not overriding a method but we are just re-declaring it. Java allows re-declaration of a method (static/non-static).
Removing the static keyword from getVehileNumber() method of Car class will result into compilation error, Since, we are trying to change the functionality of static method which belongs to Vehicle class only.
Also, If the getVehileNumber() is declared as final then the code will not compile, Since the final keyword restricts the programmer from re-declaring the method.
public static final int getVehileNumber() {
return VIN; }
Overall, this is upto software designers for where to use the static methods.
I personally prefer to use static methods to perform some actions without creating any instance of a class. Secondly, to hide the behaviour of a class from outside world.
Here is a simple explanation. A static method is associated with a class while an instance method is associated with a particular object. Overrides allow calling the different implementation of the overridden methods associated with the particular object. So it is counter-intuitive to override static method which is not even associated with objects but the class itself in the first place. So static methods cannot be overridden based on what object is calling it, it will always be associated with the class where it was created.
Now seeing above answers everyone knows that we can't override static methods, but one should not misunderstood about the concept of accessing static methods from subclass.
We can access static methods of super class with subclass reference if this static method has not been hidden by new static method defined in sub class.
For Example, see below code:-
public class StaticMethodsHiding {
public static void main(String[] args) {
SubClass.hello();
}
}
class SuperClass {
static void hello(){
System.out.println("SuperClass saying Hello");
}
}
class SubClass extends SuperClass {
// static void hello() {
// System.out.println("SubClass Hello");
// }
}
Output:-
SuperClass saying Hello
See Java oracle docs and search for What You Can Do in a Subclass for details about hiding of static methods in sub class.
Thanks
The following code shows that it is possible:
class OverridenStaticMeth {
static void printValue() {
System.out.println("Overriden Meth");
}
}
public class OverrideStaticMeth extends OverridenStaticMeth {
static void printValue() {
System.out.println("Overriding Meth");
}
public static void main(String[] args) {
OverridenStaticMeth osm = new OverrideStaticMeth();
osm.printValue();
System.out.println("now, from main");
printValue();
}
}
I'm sure you all know the behaviour I mean - code such as:
Thread thread = new Thread();
int activeCount = thread.activeCount();
provokes a compiler warning. Why isn't it an error?
EDIT:
To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:
String hello = "hello";
String number123AsString = hello.valueOf(123);
Which makes it look as if each String instance comes with a "String valueOf(int i)" method.
Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)
Just to respond to DJClayworth's point, here's what's allowed in C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?
Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?
EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
As you can see, the execution-time value of b is completely ignored.
Why should it be an error? The instance has access to all the static methods. The static methods can't change the state of the instance (trying to is a compile error).
The problem with the well-known example that you give is very specific to threads, not static method calls. It looks as though you're getting the activeCount() for the thread referred to by thread, but you're really getting the count for the calling thread. This is a logical error that you as a programmer are making. Issuing a warning is the appropriate thing for the compiler to do in this case. It's up to you to heed the warning and fix your code.
EDIT: I realize that the syntax of the language is what's allowing you to write misleading code, but remember that the compiler and its warnings are part of the language too. The language allows you to do something that the compiler considers dubious, but it gives you the warning to make sure you're aware that it could cause problems.
They cannot make it an error anymore, because of all the code that is already out there.
I am with you on that it should be an error.
Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.
Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.
Short answer - the language allows it, so its not an error.
The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by #TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that #TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.
Likely for the same logical that makes this not an error:
public class X
{
public static void foo()
{
}
public void bar()
{
foo(); // no need to do X.foo();
}
}
It isn't an error because it's part of the spec, but you're obviously asking about the rationale, which we can all guess at.
My guess is that the source of this is actually to allow a method in a class to invoke a static method in the same class without the hassle. Since calling x() is legal (even without the self class name), calling this.x() should be legal as well, and therefore calling via any object was made legal as well.
This also helps encourage users to turn private functions into static if they don't change the state.
Besides, compilers generally try to avoid declaring errors when there is no way that this could lead to a direct error. Since a static method does not change the state or care about the invoking object, it does not cause an actual error (just confusion) to allow this. A warning suffices.
The purpose of the instance variable reference is only to supply the type which encloses the static. If you look at the byte code invoking a static via instance.staticMethod or EnclosingClass.staticMethod produces the same invoke static method bytecode. No reference to the instance appears.
The answer as too why it's in there, well it just is. As long as you use the class. and not via an instance you will help avoid confusion in the future.
Probably you can change it in your IDE (in Eclipse Preferences -> Java -> Compiler -> Errors/Warnings)
There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.
It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.
Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods
$input.isEmpty()
where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.
But in Java all objects inherit from Object so our end-users can also put this to the template
$input.getClass()
to get an instance of String Class.
And with this reference they can also call a static method forName(String) on this
$input.getClass().forName("java.io.FileDescriptor")
use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)
This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.
I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
I just consider this:
instanceVar.staticMethod();
to be shorthand for this:
instanceVar.getClass().staticMethod();
If you always had to do this:
SomeClass.staticMethod();
then you wouldn't be able to leverage inheritance for static methods.
That is, by calling the static method via the instance you don't need to know what concrete class the instance is at compile time, only that it implements staticMethod() somewhere along the inheritance chain.
EDIT: This answer is wrong. See comments for details.
I've been reviewing Java Regex Library, surprised by the fact the Pattern class does not have a public constructor which I've taken for granted for years.
One reason I suspect the static compile method is being used in favor of constructor could be that constructor would always return a new object while a static method might return a previously created (and cached) object provided that the pattern string is the same.
However, it is not the case as demonstrated by the following.
public class PatternCompiler {
public static void main(String[] args) {
Pattern first = Pattern.compile(".");
Pattern second = Pattern.compile(".");
if (first == second) {
System.out.println("The same object has been reused!");
} else {
System.out.println("Why not just use constructor?");
}
}
}
Any other strong rationales behind using static method over constructor?
Edit: I found a related question here. None of the answers there convinced me either. Reading through all answers, I get a feeling that a static method has quite a few advantages over a public constructor regarding creating an object but not the other way around. Is that true? If so, I'm gonna create such static methods for each one of my classes and safely assume that it's both more readable and flexible.
Generally, a class won't have a public constructor for one of three reasons:
The class is a utility class and there is no reason to instantiate it (for example, java.lang.Math).
Instantiation can fail, and a constructor can't return null.
A static method clarifies the meaning behind what happens during instantiation.
In the class of Pattern, the third case is applicable--the static compile method is used solely for clarity. Constructing a pattern via new Pattern(..) doesn't make sense from an explanatory point of view, because there's a sophisticated process which goes on to create a new Pattern. To explain this process, the static method is named compile, because the regex is essentially compiled to create the pattern.
In short, there is no programmatic purpose for making Pattern only constructable via a static method.
One possible reason is that this way, caching can later be added into the method.
Another possible reason is readability. Consider this (often cited) object:
class Point2d{
static Point2d fromCartesian(double x, double y);
static Point2d fromPolar(double abs, double arg);
}
Point2d.fromCartesian(1, 2) and Point2d.fromPolar(1, 2) are both perfectly readable and unambiguous (well... apart from the argument order).
Now, consider new Point2d(1, 2). Are the arguments cartesian coordinates, or polar coordinates? It's even worse if constructors with similar / compatible signatures have entirely different semantics (say, int, int is cartesian, double, double is polar).
This rationale applies to any object that can be constructed in multiple different ways that don't differ in just the argument type. While Pattern, currently, can only be compiled from a regex, different representations of a Pattern may come in the future (admittably, then, compile is a bad method name).
Another possible reason, mentioned by #Vulcan, is that a constructor should not fail.
If Pattern.compile encounters an invalid pattern it throws a PatternSyntaxException. Some people may consider it a bad practice to throw an exception from a constructor. Admittably, FileInputStream does exactly that. Similarly, if the design decision was to return null from the compile method, this would not be possible with a constructor.
In short, a constructor is not a good design choice if:
caching may take place, or
the constructor is semantically ambiguous, or
the creation may fail.
This is just a design decision. In this case there is no "real" advantage. However, this design allows optimisation (caching for instance) without changing the API. See http://gbracha.blogspot.nl/2007/06/constructors-considered-harmful.html
Factory methods have several advantages, some of which are already specified in other answers. The advice to consider factory methods instead of constructors is even the very first chapter in the great book "Effective Java" from Joshua Bloch (a must-read for every Java programmer).
One advantage is that you can have several factory methods which have the same parameter signatures but different names. This you can't achieve with constructors.
For example, one might want to create a Pattern from several input formats, all of which are just Strings:
class Pattern {
compile(String regexp) { ... }
compileFromJson(String json) { ... }
compileFromXML(String xml) { ... }
}
Even if you are not doing this when you create the class, factory methods give you the ability to add such methods latter without causing weirdness.
For example, I have seen classes where the need for a new constructor came later and a special meaning-less second parameter had to be added to the second constructor in order to allow overloading. Obviously, this is very ugly:
class Ugly {
Ugly(String str) { ... }
/* This constructor interpretes str in some other way.
* The second parameter is ignored completely. */
Ugly(String str, boolean ignored) { ... }
}
Unfortunately, I can't remember the name of such a class, but I think it even was in the Java API.
Another advantage which has not been mentioned before is that with factory methods in combination with package-private constructors you can prohibit sub-classing for others, but still use sub-classes yourself. In the case of Pattern, you might want to have private sub-classes like CompiledPattern, LazilyCompiledPattern, and InterpretedPattern, but still prohibit sub-classing to ensure immutability.
With a public constructor, you can either prohibit sub-classing for everybody, or not at all.
If you really want to take the deep dive, plunge into the archives of JSR 51.
Regular expressions have been introduced as part of JSR 51, that’s where you might still find the design decisions in their archives, http://jcp.org/en/jsr/detail?id=51
It has a private constructor.
/**
* This private constructor is used to create all Patterns. The pattern
* string and match flags are all that is needed to completely describe
* a Pattern. An empty pattern string results in an object tree with
* only a Start node and a LastNode node.
*/
private Pattern(String p, int f) {
and compile method calls into that.
public static Pattern compile(String regex) {
return new Pattern(regex, 0);
}
Since you are using == comparison which is for references it will not work
The only reason I can think of this behaviour is that the match flag will be defaulted to zero in the compile method which acts a factory method.
I'm sure you all know the behaviour I mean - code such as:
Thread thread = new Thread();
int activeCount = thread.activeCount();
provokes a compiler warning. Why isn't it an error?
EDIT:
To be clear: question has nothing to do with Threads. I realise Thread examples are often given when discussing this because of the potential to really mess things up with them. But really the problem is that such usage is always nonsense and you can't (competently) write such a call and mean it. Any example of this type of method call would be barmy. Here's another:
String hello = "hello";
String number123AsString = hello.valueOf(123);
Which makes it look as if each String instance comes with a "String valueOf(int i)" method.
Basically I believe the Java designers made a mistake when they designed the language, and it's too late to fix it due to the compatibility issues involved. Yes, it can lead to very misleading code. Yes, you should avoid it. Yes, you should make sure your IDE is configured to treat it as an error, IMO. Should you ever design a language yourself, bear it in mind as an example of the kind of thing to avoid :)
Just to respond to DJClayworth's point, here's what's allowed in C#:
public class Foo
{
public static void Bar()
{
}
}
public class Abc
{
public void Test()
{
// Static methods in the same class and base classes
// (and outer classes) are available, with no
// qualification
Def();
// Static methods in other classes are available via
// the class name
Foo.Bar();
Abc abc = new Abc();
// This would *not* be legal. It being legal has no benefit,
// and just allows misleading code
// abc.Def();
}
public static void Def()
{
}
}
Why do I think it's misleading? Because if I look at code someVariable.SomeMethod() I expect it to use the value of someVariable. If SomeMethod() is a static method, that expectation is invalid; the code is tricking me. How can that possibly be a good thing?
Bizarrely enough, Java won't let you use a potentially uninitialized variable to call a static method, despite the fact that the only information it's going to use is the declared type of the variable. It's an inconsistent and unhelpful mess. Why allow it?
EDIT: This edit is a response to Clayton's answer, which claims it allows inheritance for static methods. It doesn't. Static methods just aren't polymorphic. Here's a short but complete program to demonstrate that:
class Base
{
static void foo()
{
System.out.println("Base.foo()");
}
}
class Derived extends Base
{
static void foo()
{
System.out.println("Derived.foo()");
}
}
public class Test
{
public static void main(String[] args)
{
Base b = new Derived();
b.foo(); // Prints "Base.foo()"
b = null;
b.foo(); // Still prints "Base.foo()"
}
}
As you can see, the execution-time value of b is completely ignored.
Why should it be an error? The instance has access to all the static methods. The static methods can't change the state of the instance (trying to is a compile error).
The problem with the well-known example that you give is very specific to threads, not static method calls. It looks as though you're getting the activeCount() for the thread referred to by thread, but you're really getting the count for the calling thread. This is a logical error that you as a programmer are making. Issuing a warning is the appropriate thing for the compiler to do in this case. It's up to you to heed the warning and fix your code.
EDIT: I realize that the syntax of the language is what's allowing you to write misleading code, but remember that the compiler and its warnings are part of the language too. The language allows you to do something that the compiler considers dubious, but it gives you the warning to make sure you're aware that it could cause problems.
They cannot make it an error anymore, because of all the code that is already out there.
I am with you on that it should be an error.
Maybe there should be an option/profile for the compiler to upgrade some warnings to errors.
Update: When they introduced the assert keyword in 1.4, which has similar potential compatibility issues with old code, they made it available only if you explicitly set the source mode to "1.4". I suppose one could make a it an error in a new source mode "java 7". But I doubt they would do it, considering that all the hassle it would cause. As others have pointed out, it is not strictly necessary to prevent you from writing confusing code. And language changes to Java should be limited to the strictly necessary at this point.
Short answer - the language allows it, so its not an error.
The really important thing, from the compiler's perspective, is that it be able to resolve symbols. In the case of a static method, it needs to know what class to look in for it -- since it's not associated with any particular object. Java's designers obviously decided that since they could determine the class of an object, they could also resolve the class of any static method for that object from any instance of the object. They choose to allow this -- swayed, perhaps, by #TofuBeer's observation -- to give the programmer some convenience. Other language designers have made different choices. I probably would have fallen into the latter camp, but it's not that big of a deal to me. I probably would allow the usage that #TofuBeer mentions, but having allowed it my position on not allowing access from an instance variable is less tenable.
Likely for the same logical that makes this not an error:
public class X
{
public static void foo()
{
}
public void bar()
{
foo(); // no need to do X.foo();
}
}
It isn't an error because it's part of the spec, but you're obviously asking about the rationale, which we can all guess at.
My guess is that the source of this is actually to allow a method in a class to invoke a static method in the same class without the hassle. Since calling x() is legal (even without the self class name), calling this.x() should be legal as well, and therefore calling via any object was made legal as well.
This also helps encourage users to turn private functions into static if they don't change the state.
Besides, compilers generally try to avoid declaring errors when there is no way that this could lead to a direct error. Since a static method does not change the state or care about the invoking object, it does not cause an actual error (just confusion) to allow this. A warning suffices.
The purpose of the instance variable reference is only to supply the type which encloses the static. If you look at the byte code invoking a static via instance.staticMethod or EnclosingClass.staticMethod produces the same invoke static method bytecode. No reference to the instance appears.
The answer as too why it's in there, well it just is. As long as you use the class. and not via an instance you will help avoid confusion in the future.
Probably you can change it in your IDE (in Eclipse Preferences -> Java -> Compiler -> Errors/Warnings)
There's not option for it. In java (like many other lang.) you can have access to all static members of a class through its class name or instance object of that class. That would be up to you and your case and software solution which one you should use that gives you more readability.
It's pretty old topic but still up-to-date and surprisingly bringing higher impact nowadays. As Jon mentioned, it might be just a mistake Java's designers made at the very beginning. But I wouldn't imagine before it can have impact on security.
Many coders know Apache Velocity, flexible and powerful template engine. It's so powerful that it allows to feed template with a set of named objects - stricly considered as objects from programming language (Java originally). Those objects can be accessed from within template like in programming language so for example Java's String instance can be used with all its public fields, properties and methods
$input.isEmpty()
where input is a String, runs directly through JVM and returns true or false to Velocity parser's output). So far so good.
But in Java all objects inherit from Object so our end-users can also put this to the template
$input.getClass()
to get an instance of String Class.
And with this reference they can also call a static method forName(String) on this
$input.getClass().forName("java.io.FileDescriptor")
use any class name and use it to whatever web server's account can do (deface, steal DB content, inspect config files, ...)
This exploit is somehow (in specific context) described here: https://github.com/veracode-research/solr-injection#7-cve-2019-17558-rce-via-velocity-template-by-_s00py
It wouldn't be possible if calling static methods from reference to the instance of class was prohibited.
I'm not saying that a particular programming framework is better than the other one or so but I just want to put a comparison. There's a port of Apache Velocity for .NET. In C# it's not possible to call static methods just from instance's reference what makes exploit like this useless:
$input.GetType().GetType("System.IO.FileStream, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
I just consider this:
instanceVar.staticMethod();
to be shorthand for this:
instanceVar.getClass().staticMethod();
If you always had to do this:
SomeClass.staticMethod();
then you wouldn't be able to leverage inheritance for static methods.
That is, by calling the static method via the instance you don't need to know what concrete class the instance is at compile time, only that it implements staticMethod() somewhere along the inheritance chain.
EDIT: This answer is wrong. See comments for details.
Closed. This question is opinion-based. It is not currently accepting answers.
Closed 5 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I've seen examples like this:
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
and supposed that I could have a Constants class to wrap constants in, declaring them static final. I know practically no Java at all and am wondering if this is the best way to create constants.
That is perfectly acceptable, probably even the standard.
(public/private) static final TYPE NAME = VALUE;
where TYPE is the type, NAME is the name in all caps with underscores for spaces, and VALUE is the constant value;
I highly recommend NOT putting your constants in their own classes or interfaces.
As a side note: Variables that are declared final and are mutable can still be changed; however, the variable can never point at a different object.
For example:
public static final Point ORIGIN = new Point(0,0);
public static void main(String[] args){
ORIGIN.x = 3;
}
That is legal and ORIGIN would then be a point at (3, 0).
I would highly advise against having a single constants class. It may seem a good idea at the time, but when developers refuse to document constants and the class grows to encompass upwards of 500 constants which are all not related to each other at all (being related to entirely different aspects of the application), this generally turns into the constants file being completely unreadable. Instead:
If you have access to Java 5+, use enums to define your specific constants for an application area. All parts of the application area should refer to enums, not constant values, for these constants. You may declare an enum similar to how you declare a class. Enums are perhaps the most (and, arguably, only) useful feature of Java 5+.
If you have constants that are only valid to a particular class or one of its subclasses, declare them as either protected or public and place them on the top class in the hierarchy. This way, the subclasses can access these constant values (and if other classes access them via public, the constants aren't only valid to a particular class...which means that the external classes using this constant may be too tightly coupled to the class containing the constant)
If you have an interface with behavior defined, but returned values or argument values should be particular, it is perfectly acceptible to define constants on that interface so that other implementors will have access to them. However, avoid creating an interface just to hold constants: it can become just as bad as a class created just to hold constants.
It is a BAD PRACTICE to use interfaces just to hold constants (named constant interface pattern by Josh Bloch). Here's what Josh advises:
If the constants are strongly tied to
an existing class or interface, you
should add them to the class or
interface. For example, all of the
boxed numerical primitive classes,
such as Integer and Double, export
MIN_VALUE and MAX_VALUE constants. If
the constants are best viewed as
members of an enumerated type, you
should export them with an enum
type. Otherwise, you should export the
constants with a noninstantiable
utility class.
Example:
// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
private PhysicalConstants() { } // Prevents instantiation
public static final double AVOGADROS_NUMBER = 6.02214199e23;
public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
public static final double ELECTRON_MASS = 9.10938188e-31;
}
About the naming convention:
By convention, such fields have names
consisting of capital letters, with
words separated by underscores. It is
critical that these fields contain
either primitive values or references
to immutable objects.
In Effective Java (2nd edition), it's recommended that you use enums instead of static ints for constants.
There's a good writeup on enums in Java here:
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
Note that at the end of that article the question posed is:
So when should you use enums?
With an answer of:
Any time you need a fixed set of constants
Just avoid using an interface:
public interface MyConstants {
String CONSTANT_ONE = "foo";
}
public class NeddsConstant implements MyConstants {
}
It is tempting, but violates encapsulation and blurs the distinction of class definitions.
I use following approach:
public final class Constants {
public final class File {
public static final int MIN_ROWS = 1;
public static final int MAX_ROWS = 1000;
private File() {}
}
public final class DB {
public static final String name = "oups";
public final class Connection {
public static final String URL = "jdbc:tra-ta-ta";
public static final String USER = "testUser";
public static final String PASSWORD = "testPassword";
private Connection() {}
}
private DB() {}
}
private Constants() {}
}
Than, for example, I use Constants.DB.Connection.URL to get constant.
It looks more "object oriently" as for me.
Creating static final constants in a separate class can get you into trouble. The Java compiler will actually optimize this and place the actual value of the constant into any class that references it.
If you later change the 'Constants' class and you don't do a hard re-compile on other classes that reference that class, you will wind up with a combination of old and new values being used.
Instead of thinking of these as constants, think of them as configuration parameters and create a class to manage them. Have the values be non-final, and even consider using getters. In the future, as you determine that some of these parameters actually should be configurable by the user or administrator, it will be much easier to do.
The number one mistake you can make is creating a globally accessible class called with a generic name, like Constants. This simply gets littered with garbage and you lose all ability to figure out what portion of your system uses these constants.
Instead, constants should go into the class which "owns" them. Do you have a constant called TIMEOUT? It should probably go into your Communications() or Connection() class. MAX_BAD_LOGINS_PER_HOUR? Goes into User(). And so on and so forth.
The other possible use is Java .properties files when "constants" can be defined at run-time, but not easily user changeable. You can package these up in your .jars and reference them with the Class resourceLoader.
That's the right way to go.
Generally constants are not kept in separate "Constants" classes because they're not discoverable. If the constant is relevant to the current class, keeping them there helps the next developer.
What about an enumeration?
I prefer to use getters rather than constants. Those getters might return constant values, e.g. public int getMaxConnections() {return 10;}, but anything that needs the constant will go through a getter.
One benefit is that if your program outgrows the constant--you find that it needs to be configurable--you can just change how the getter returns the constant.
The other benefit is that in order to modify the constant you don't have to recompile everything that uses it. When you reference a static final field, the value of that constant is compiled into any bytecode that references it.
I agree that using an interface is not the way to go. Avoiding this pattern even has its own item (#18) in Bloch's Effective Java.
An argument Bloch makes against the constant interface pattern is that use of constants is an implementation detail, but implementing an interface to use them exposes that implementation detail in your exported API.
The public|private static final TYPE NAME = VALUE; pattern is a good way of declaring a constant. Personally, I think it's better to avoid making a separate class to house all of your constants, but I've never seen a reason not to do this, other than personal preference and style.
If your constants can be well-modeled as an enumeration, consider the enum structure available in 1.5 or later.
If you're using a version earlier than 1.5, you can still pull off typesafe enumerations by using normal Java classes. (See this site for more on that).
Based on the comments above I think this is a good approach to change the old-fashioned global constant class (having public static final variables) to its enum-like equivalent in a way like this:
public class Constants {
private Constants() {
throw new AssertionError();
}
public interface ConstantType {}
public enum StringConstant implements ConstantType {
DB_HOST("localhost");
// other String constants come here
private String value;
private StringConstant(String value) {
this.value = value;
}
public String value() {
return value;
}
}
public enum IntConstant implements ConstantType {
DB_PORT(3128),
MAX_PAGE_SIZE(100);
// other int constants come here
private int value;
private IntConstant(int value) {
this.value = value;
}
public int value() {
return value;
}
}
public enum SimpleConstant implements ConstantType {
STATE_INIT,
STATE_START,
STATE_END;
}
}
So then I can refer them to like:
Constants.StringConstant.DB_HOST
A good object oriented design should not need many publicly available constants. Most constants should be encapsulated in the class that needs them to do its job.
There is a certain amount of opinion to answer this. To start with, constants in java are generally declared to be public, static and final. Below are the reasons:
public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
makes little sense to duplicate them for every object.
final, since they should not be allowed to change
I would never use an interface for a CONSTANTS accessor/object simply because interfaces are generally expected to be implemented. Wouldn't this look funny:
String myConstant = IMyInterface.CONSTANTX;
Instead I would choose between a few different ways, based on some small trade-offs, and so it depends on what you need:
1. Use a regular enum with a default/private constructor. Most people would define
constants this way, IMHO.
- drawback: cannot effectively Javadoc each constant member
- advantage: var members are implicitly public, static, and final
- advantage: type-safe
- provides "a limited constructor" in a special way that only takes args which match
predefined 'public static final' keys, thus limiting what you can pass to the
constructor
2. Use a altered enum WITHOUT a constructor, having all variables defined with
prefixed 'public static final' .
- looks funny just having a floating semi-colon in the code
- advantage: you can JavaDoc each variable with an explanation
- drawback: you still have to put explicit 'public static final' before each variable
- drawback: not type-safe
- no 'limited constructor'
3. Use a Class with a private constructor:
- advantage: you can JavaDoc each variable with an explanation
- drawback: you have to put explicit 'public static final' before each variable
- you have the option of having a constructor to create an instance
of the class if you want to provide additional functions related
to your constants
(or just keep the constructor private)
- drawback: not type-safe
4. Using interface:
- advantage: you can JavaDoc each variable with an explanation
- advantage: var members are implicitly 'public static final'
- you are able to define default interface methods if you want to provide additional
functions related to your constants (only if you implement the interface)
- drawback: not type-safe
What is the best way to implement constants in Java?
One approach that we should really avoid : using interfaces to define constants.
Creating a interface specifically to declare constants is really the worst thing : it defeats the reason why interfaces were designed : defining method(s) contract.
Even if an interface already exists to address a specific need, declaring the constants in them make really not sense as constants should not make part of the API and the contract provided to client classes.
To simplify, we have broadly 4 valid approaches.
With static final String/Integer field :
1) using a class that declares constants inside but not only.
1 variant) creating a class dedicated to only declare constants.
With Java 5 enum :
2) declaring the enum in a related purpose class (so as a nested class).
2 variant) creating the enum as a standalone class (so defined in its own class file).
TLDR : Which is the best way and where locate the constants ?
In most of cases, the enum way is probably finer than the static final String/Integer way and personally I think that the static final String/Integer way should be used only if we have good reasons to not use enums.
And about where we should declare the constant values, the idea is to search whether there is a single existing class that owns a specific and strong functional cohesion with constant values. If we find such a class, we should use it as the constants holder. Otherwise, the constant should be associated to no one particular class.
static final String/ static final Integer versus enum
Enums usage is really a way to strongly considered.
Enums have a great advantage over String or Integer constant field.
They set a stronger compilation constraint.
If you define a method that takes the enum as parameter, you can only pass a enum value defined in the enum class(or null).
With String and Integer you can substitute them with any values of compatible type and the compilation will be fine even if the value is not a defined constant in the static final String/ static final Integer fields.
For example, below two constants defined in a class as static final String fields :
public class MyClass{
public static final String ONE_CONSTANT = "value";
public static final String ANOTHER_CONSTANT = "other value";
. . .
}
Here a method that expects to have one of these constants as parameter :
public void process(String constantExpected){
...
}
You can invoke it in this way :
process(MyClass.ONE_CONSTANT);
or
process(MyClass.ANOTHER_CONSTANT);
But no compilation constraint prevents you from invoking it in this way :
process("a not defined constant value");
You would have the error only at runtime and only if you do at a time a check on the transmitted value.
With enum, checks are not required as the client could only pass a enum value in a enum parameter.
For example, here two values defined in a enum class (so constant out of the box):
public enum MyEnum {
ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");
private String value;
MyEnum(String value) {
this.value = value;
}
...
}
Here a method that expects to have one of these enum values as parameter :
public void process(MyEnum myEnum){
...
}
You can invoke it in this way :
process(MyEnum.ONE_CONSTANT);
or
process(MyEnum.ANOTHER_CONSTANT);
But the compilation will never allow you from invoking it in this way :
process("a not defined constant value");
Where should we declare the constants ?
If your application contains a single existing class that owns a specific and strong functional cohesion with the constant values, the 1) and the 2) appear more intuitive.
Generally, it eases the use of the constants if these are declared in the main class that manipulates them or that has a name very natural to guess that we will find it inside.
For example in the JDK library, the exponential and pi constant values are declared in a class that declare not only constant declarations (java.lang.Math).
public final class Math {
...
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;
...
}
The clients using mathematics functions rely often on the Math class.
So, they may find constants easily enough and can also remember where E and PI are defined in a very natural way.
If your application doesn't contain an existing class that has a very specific and strong functional cohesion with the constant values, the 1 variant) and the 2 variant) ways appear more intuitive.
Generally, it doesn't ease the use of the constants if these are declared in one class that manipulates them while we have also 3 or 4 other classes that manipulate them as much as and no one of these classes seems be more natural than others to host constant values.
Here, defining a custom class to hold only constant values makes sense.
For example in the JDK library, the java.util.concurrent.TimeUnit enum is not declared in a specific class as there is not really one and only one JDK specific class that appear as the most intuitive to hold it :
public enum TimeUnit {
NANOSECONDS {
.....
},
MICROSECONDS {
.....
},
MILLISECONDS {
.....
},
SECONDS {
.....
},
.....
}
Many classes declared in java.util.concurrent use them :
BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ... and really no one of them seems more appropriate to hold the enum.
A Constant, of any type, can be declared by creating an immutable property that within a class (that is a member variable with the final modifier). Typically the static and public modifiers are also provided.
public class OfficePrinter {
public static final String STATE = "Ready";
}
There are numerous applications where a constant's value indicates a selection from an n-tuple (e.g. enumeration) of choices. In our example, we can choose to define an Enumerated Type that will restrict the possible assigned values (i.e. improved type-safety):
public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}
A single, generic constants class is a bad idea. Constants should be grouped together with the class they're most logically related to.
Rather than using variables of any kind (especially enums), I would suggest that you use methods. Create a method with the same name as the variable and have it return the value you assigned to the variable. Now delete the variable and replace all references to it with calls to the method you just created. If you feel that the constant is generic enough that you shouldn't have to create an instance of the class just to use it, then make the constant method a class method.
FWIW, a timeout in seconds value should probably be a configuration setting (read in from a properties file or through injection as in Spring) and not a constant.
What is the difference
1.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
2.
public class MyGlobalConstants {
private MyGlobalConstants () {} // Prevents instantiation
public static final int TIMEOUT_IN_SECS = 25;
}
and using
MyGlobalConstants.TIMEOUT_IN_SECS wherever we need this constant. I think both are same.
I wouldn't call the class the same (aside from casing) as the constant ... I would have at a minimum one class of "Settings", or "Values", or "Constants", where all the constants would live. If I have a large number of them, I'd group them up in logical constant classes (UserSettings, AppSettings, etc.)
To take it a step further, you can place globally used constants in an interface so they can be used system wide. E.g.
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
But don't then implement it. Just refer to them directly in code via the fully qualified classname.
For Constants, Enum is a better choice IMHO. Here is an example
public class myClass {
public enum myEnum {
Option1("String1", 2),
Option2("String2", 2)
;
String str;
int i;
myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }
}
One of the way I do it is by creating a 'Global' class with the constant values and do a static import in the classes that need access to the constant.
static final is my preference, I'd only use an enum if the item was indeed enumerable.
I use static final to declare constants and go with the ALL_CAPS naming notation. I have seen quite a few real life instances where all constants are bunched together into an interface. A few posts have rightly called that a bad practice, primarily because that's not what an interface is for. An interface should enforce a contract and should not be a place to put unrelated constants in. Putting it together into a class that cannot be instantiated (through a private constructor) too is fine if the constant semantics don't belong to a specific class(es). I always put a constant in the class that it's most related to, because that makes sense and is also easily maintainable.
Enums are a good choice to represent a range of values, but if you are storing standalone constants with an emphasis on the absolute value (eg. TIMEOUT = 100 ms) you can just go for the static final approach.
I agree with what most are saying, it is best to use enums when dealing with a collection of constants. However, if you are programming in Android there is a better solution: IntDef Annotation.
#Retention(SOURCE)
#IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public #interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(#NavigationMode int mode);
#NavigationMode
public abstract int getNavigationMode();
IntDef annotation is superior to enums in one simple way, it takes significantly less space as it is simply a compile-time marker. It is not a class, nor does it have the automatic string-conversion property.
It is BAD habit and terribly
ANNOYING practice to quote Joshua Bloch without understanding the basic ground-zero fundamentalism.
I have not read anything Joshua Bloch, so either
he is a terrible programmer
or the people so far whom I find quoting him (Joshua is the name of a boy I presume) are simply using his material as religious scripts to justify their software religious indulgences.
As in Bible fundamentalism all the biblical laws can be summed up by
Love the Fundamental Identity with all your heart and all your mind
Love your neighbour as yourself
and so similarly software engineering fundamentalism can be summed up by
devote yourself to the ground-zero fundamentals with all your programming might and mind
and devote towards the excellence of your fellow-programmers as you would for yourself.
Also, among biblical fundamentalist circles a strong and reasonable corollary is drawn
First love yourself. Because if you don't love yourself much, then the concept "love your neighbour as yourself" doesn't carry much weight, since "how much you love yourself" is the datum line above which you would love others.
Similarly, if you do not respect yourself as a programmer and just accept the pronouncements and prophecies of some programming guru-nath WITHOUT questioning the fundamentals, your quotations and reliance on Joshua Bloch (and the like) is meaningless. And therefore, you would actually have no respect for your fellow-programmers.
The fundamental laws of software programming
laziness is the virtue of a good programmer
you are to make your programming life as easy, as lazy and therefore as effective as possible
you are to make the consequences and entrails of your programming as easy, as lazy and therefore as effective as possible for your neigbour-programmers who work with you and pick up your programming entrails.
Interface-pattern constants is a bad habit ???
Under what laws of fundamentally effective and responsible programming does this religious edict fall into ?
Just read the wikipedia article on interface-pattern constants (https://en.wikipedia.org/wiki/Constant_interface), and the silly excuses it states against interface-pattern constants.
Whatif-No IDE? Who on earth as a software programmer would not use an IDE? Most of us are programmers who prefer not to have to prove having macho aescetic survivalisticism thro avoiding the use of an IDE.
Also - wait a second proponents of micro-functional programming as a means of not needing an IDE. Wait till you read my explanation on data-model normalization.
Pollutes the namespace with variables not used within the current scope? It could be proponents of this opinion
are not aware of, and the need for, data-model normalization
Using interfaces for enforcing constants is an abuse of interfaces. Proponents of such have a bad habit of
not seeing that "constants" must be treated as contract. And interfaces are used for enforcing or projecting compliance to a contract.
It is difficult if not impossible to convert interfaces into implemented classes in the future. Hah .... hmmm ... ???
Why would you want to engage in such pattern of programming as your persistent livelihood? IOW, why devote yourself to such an AMBIVALENT and bad programming habit ?
Whatever the excuses, there is NO VALID EXCUSE when it comes to FUNDAMENTALLY EFFECTIVE software engineering to delegitimize or generally discourage the use of interface constants.
It doesn't matter what the original intents and mental states of the founding fathers who crafted the United States Constitution were. We could debate the original intents of the founding fathers but all I care is the written statements of the US Constitution. And it is the responsibility of every US citizen to exploit the written literary-fundamentalism, not the unwritten founding-intents, of the US Constitution.
Similarly, I do not care what the "original" intents of the founders of the Java platform and programming language had for the interface. What I care are the effective features the Java specification provides, and I intend to exploit those features to the fullest to help me fulfill the fundamental laws of responsible software programming. I don't care if I am perceived to "violate the intention for interfaces". I don't care what Gosling or someone Bloch says about the "proper way to use Java", unless what they say does not violate my need to EFFECTIVE fulfilling fundamentals.
The Fundamental is Data-Model Normalization
It doesn't matter how your data-model is hosted or transmitted. Whether you use interfaces or enums or whatevernots, relational or no-SQL, if you don't understand the need and process of data-model normalization.
We must first define and normalize the data-model of a set of processes. And when we have a coherent data-model, ONLY then can we use the process flow of its components to define the functional behaviour and process blocks a field or realm of applications. And only then can we define the API of each functional process.
Even the facets of data normalization as proposed by EF Codd is now severely challenged and severely-challenged. e.g. his statement on 1NF has been criticized as ambiguous, misaligned and over-simplified, as is the rest of his statements especially in the advent of modern data services, repo-technology and transmission. IMO, the EF Codd statements should be completely ditched and new set of more mathematically plausible statements be designed.
A glaring flaw of EF Codd's and the cause of its misalignment to effective human comprehension is his belief that humanly perceivable multi-dimensional, mutable-dimension data can be efficiently perceived thro a set of piecemeal 2-dimensional mappings.
The Fundamentals of Data Normalization
What EF Codd failed to express.
Within each coherent data-model, these are the sequential graduated order of data-model coherence to achieve.
The Unity and Identity of data instances.
design the granularity of each data component, whereby their granularity is at a level where each instance of a component can be uniquely identified and retrieved.
absence of instance aliasing. i.e., no means exist whereby an identification produces more than one instance of a component.
Absence of instance crosstalk. There does not exist the necessity to use one or more other instances of a component to contribute to identifying an instance of a component.
The unity and identity of data components/dimensions.
Presence of component de-aliasing. There must exist one definition whereby a component/dimension can be uniquely identified. Which is the primary definition of a component;
where the primary definition will not result in exposing sub-dimensions or member-components that are not part of an intended component;
Unique means of component dealiasing. There must exist one, and only one, such component de-aliasing definition for a component.
There exists one, and only one, definition interface or contract to identify a parent component in a hierarchical relationship of components.
Absence of component crosstalk. There does not exist the necessity to use a member of another component to contribute to the definitive identification of a component.
In such a parent-child relationship, the identifying definition of a parent must not depend on part of the set of member components of a child. A member component of a parent's identity must be the complete child identity without resorting to referencing any or all of the children of a child.
Preempt bi-modal or multi-modal appearances of a data-model.
When there exists two candidate definitions of a component, it is an obvious sign that there exists two different data-models being mixed up as one. That means there is incoherence at the data-model level, or the field level.
A field of applications must use one and only one data-model, coherently.
Detect and identify component mutation. Unless you have performed statistical component analysis of huge data, you probably do not see, or see the need to treat, component mutation.
A data-model may have its some of its components mutate cyclically or gradually.
The mode may be member-rotation or transposition-rotation.
Member-rotation mutation could be distinct swapping of child components between components. Or where completely new components would have to be defined.
Transpositional mutation would manifest as a dimensional-member mutating into an attribute, vice versa.
Each mutation cycle must be identified as a distinct data-modal.
Versionize each mutation. Such that you can pull out a previous version of the data model, when perhaps the need arise to treat an 8 year old mutation of the data model.
In a field or grid of inter-servicing component-applications, there must be one and only one coherent data-model or exists a means for a data-model/version to identify itself.
Are we still asking if we could use Interface Constants? Really ?
There are data-normalization issues at stake more consequential than this mundane question. IF you don't solve those issues, the confusion that you think interface constants cause is comparatively nothing. Zilch.
From the data-model normalization then you determine the components as variables, as properties, as contract interface constants.
Then you determine which goes into value injection, property configuration placeholding, interfaces, final strings, etc.
If you have to use the excuse of needing to locate a component easier to dictate against interface constants, it means you are in the bad habit of not practicing data-model normalization.
Perhaps you wish to compile the data-model into a vcs release. That you can pull out a distinctly identifiable version of a data-model.
Values defined in interfaces are completely assured to be non-mutable. And shareable. Why load a set of final strings into your class from another class when all you need is that set of constants ??
So why not this to publish a data-model contract? I mean if you can manage and normalize it coherently, why not? ...
public interface CustomerService {
public interface Label{
char AssignmentCharacter = ':';
public interface Address{
String Street = "Street";
String Unit= "Unit/Suite";
String Municipal = "City";
String County = "County";
String Provincial = "State";
String PostalCode = "Zip"
}
public interface Person {
public interface NameParts{
String Given = "First/Given name"
String Auxiliary = "Middle initial"
String Family = "Last name"
}
}
}
}
Now I can reference my apps' contracted labels in a way such as
CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
This confuses the contents of the jar file? As a Java programmer I don't care about the structure of the jar.
This presents complexity to osgi-motivated runtime swapping ? Osgi is an extremely efficient means to allow programmers to continue in their bad habits. There are better alternatives than osgi.
Or why not this? There is no leakage of of the private Constants into published contract. All private constants should be grouped into a private interface named "Constants", because I don't want to have to search for constants and I am too lazy to repeatedly type "private final String".
public class PurchaseRequest {
private interface Constants{
String INTERESTINGName = "Interesting Name";
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
Perhaps even this:
public interface PurchaseOrderConstants {
public interface Properties{
default String InterestingName(){
return something();
}
String OFFICIALLanguage = "Official Language"
int MAXNames = 9;
}
}
The only issue with interface constants worth considering is when the interface is implemented.
This is not the "original intention" of interfaces? Like I would care about the "original intention" of the founding fathers in crafting the US Constitution, rather than how the Supreme Court would interpret the written letters of the US Constitution ???
After all, I live in the land of the free, the wild and home of the brave. Be brave, be free, be wild - use the interface. If my fellow-programmers refuse to use efficient and lazy means of programming, am I obliged by the golden rule to lessen my programming efficiency to align with theirs? Perhaps I should, but that is not an ideal situation.