I understand that in this code:
class Foo {
public static void method() {
System.out.println("in Foo");
}
}
class Bar extends Foo {
public static void method() {
System.out.println("in Bar");
}
}
.. the static method in Bar 'hides' the static method declared in Foo, as opposed to overriding it in the polymorphism sense.
class Test {
public static void main(String[] args) {
Foo.method();
Bar.method();
}
}
...will output:
in Foo
in Bar
Re-defining method() as final in Foo will disable the ability for Bar to hide it, and re-running main() will output:
in Foo
in Foo
(Edit: Compilation fails when you mark the method as final, and only runs again when I remove Bar.method())
Is it considered bad practice to declare static methods as final, if it stops subclasses from intentionally or inadvertantly re-defining the method?
(this is a good explanation of what the behaviour of using final is..)
I don't consider it's bad practice to mark a static method as final.
As you found out, final will prevent the method from being hidden by subclasses which is very good news imho.
I'm quite surprised by your statement:
Re-defining method() as final in Foo will disable the ability for Bar to hide it, and re-running main() will output:
in Foo
in Foo
No, marking the method as final in Foo will prevent Bar from compiling. At least in Eclipse I'm getting:
Exception in thread "main" java.lang.Error: Unresolved compilation problem: Cannot override the final method from Foo
Also, I think people should always invoke static method qualifying them with the class name even within the class itself:
class Foo
{
private static final void foo()
{
System.out.println("hollywood!");
}
public Foo()
{
foo(); // both compile
Foo.foo(); // but I prefer this one
}
}
Static methods are one of Java's most confusing features. Best practices are there to fix this, and making all static methods final is one of these best practices!
The problem with static methods is that
they are not class methods, but global functions prefixed with a classname
it is strange that they are "inherited" to subclasses
it is surprising that they cannot be overridden but hidden
it is totally broken that they can be called with an instance as receiver
therefore you should
always call them with their class as receiver
always call them with the declaring class only as receiver
always make them (or the declaring class) final
and you should
never call them with an instance as receiver
never call them with a subclass of their declaring class as receiver
never redefine them in subclasses
NB: the second version of you program should fails a compilation error. I presume your IDE is hiding this fact from you!
If I have a public static method, then it's often already located in a so-called utility class with only static methods. Self-explaining examples are StringUtil, SqlUtil, IOUtil, etcetera. Those utility classes are by itselves already declared final and supplied with a private constructor. E.g.
public final class SomeUtil {
private SomeUtil() {
// Hide c'tor.
}
public static SomeObject doSomething(SomeObject argument1) {
// ...
}
public static SomeObject doSomethingElse(SomeObject argument1) {
// ...
}
}
This way you cannot override them.
If yours is not located in kind of an utility class, then I'd question the value of the public modifier. Shouldn't it be private? Else just move it out to some utility class. Do not clutter "normal" classes with public static methods. This way you also don't need to mark them final.
Another case is a kind of abstract factory class, which returns concrete implementations of self through a public static method. In such case it would perfectly make sense to mark the method final, you don't want the concrete implementations be able to override the method.
Usually with utility classes - classes with only static methods - it is undesirable to use inheritence. for this reason you may want to define the class as final to prevent other classes extending it. This would negate putting final modifiers on your utility class methods.
The code does not compile:
Test.java:8: method() in Bar cannot
override method() in Foo; overridden
method is static final
public static void method() {
The message is misleading since a static method can, by definition, never be overridden.
I do the following when coding (not 100% all the time, but nothing here is "wrong":
(The first set of "rules" are done for most things - some special cases are covered after)
create an interface
create an abstract class that implements the interface
create concrete classes that extend the abstract class
create concrete classes that implements the interface but do not extend the abstract class
always, if possible, make all variables/constants/parameters of the interface
Since an interface cannot have static methods you don't wind up with the issue. If you are going to make static methods in the abstract class or concrete classes they must be private, then there is no way to try to override them.
Special cases:
Utility classes (classes with all static methods):
declare the class as final
give it a private constructor to prevent accidental creation
If you want to have a static method in a concrete or abstract class that is not private you probably want to instead create a utility class instead.
Value classes (a class that is very specialized to essentially hold data, like java.awt.Point where it is pretty much holding x and y values):
no need to create an interface
no need to create an abstract class
class should be final
non-private static methods are OK, especially for construction as you may want to perform caching.
If you follow the above advice you will wind up with pretty flexible code that also has fairly clean separation of responsibilities.
An example value class is this Location class:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class Location
implements Comparable<Location>
{
// should really use weak references here to help out with garbage collection
private static final Map<Integer, Map<Integer, Location>> locations;
private final int row;
private final int col;
static
{
locations = new HashMap<Integer, Map<Integer, Location>>();
}
private Location(final int r,
final int c)
{
if(r < 0)
{
throw new IllegalArgumentException("r must be >= 0, was: " + r);
}
if(c < 0)
{
throw new IllegalArgumentException("c must be >= 0, was: " + c);
}
row = r;
col = c;
}
public int getRow()
{
return (row);
}
public int getCol()
{
return (col);
}
// this ensures that only one location is created for each row/col pair... could not
// do that if the constructor was not private.
public static Location fromRowCol(final int row,
final int col)
{
Location location;
Map<Integer, Location> forRow;
if(row < 0)
{
throw new IllegalArgumentException("row must be >= 0, was: " + row);
}
if(col < 0)
{
throw new IllegalArgumentException("col must be >= 0, was: " + col);
}
forRow = locations.get(row);
if(forRow == null)
{
forRow = new HashMap<Integer, Location>(col);
locations.put(row, forRow);
}
location = forRow.get(col);
if(location == null)
{
location = new Location(row, col);
forRow.put(col, location);
}
return (location);
}
private static void ensureCapacity(final List<?> list,
final int size)
{
while(list.size() <= size)
{
list.add(null);
}
}
#Override
public int hashCode()
{
// should think up a better way to do this...
return (row * col);
}
#Override
public boolean equals(final Object obj)
{
final Location other;
if(obj == null)
{
return false;
}
if(getClass() != obj.getClass())
{
return false;
}
other = (Location)obj;
if(row != other.row)
{
return false;
}
if(col != other.col)
{
return false;
}
return true;
}
#Override
public String toString()
{
return ("[" + row + ", " + col + "]");
}
public int compareTo(final Location other)
{
final int val;
if(row == other.row)
{
val = col - other.col;
}
else
{
val = row - other.row;
}
return (val);
}
}
It might be a good thing to mark static methods as final, particularly if you are developing a framework that you expect others to extend. That way your users won't inadvertently end up hiding your static methods in their classes. But if you are developing a framework you might want to avoid using static methods to begin with.
Most of this final issue dates back to the time when VM-s were quite dumb/conservative. Back then if you marked a method final it meant (among other things), that the VM can inline it, avoiding method calls. That is not case since a long-long (or long double :P ) time: http://java.sun.com/developer/technicalArticles/Networking/HotSpot/inlining.html .
I guess that Idea/Netbeans inspection warns you, because it thinks that you want to use the final keyword for optimization and they think that you are unaware of the fact that it is unneeded with modern VMs.
Just my two cents...
I encountered one detriment to using final methods using Spring's AOP and MVC. I was trying to use spring's AOP put in security hooks around one of the methods in the AbstractFormController which was declared final. I think spring was using the bcel library for injection in classes and there was some limitation there.
When I create pure utility classes, I declare then with a private constructor so they cannot be extended. When creating normal classes, I declare my methods static if they are not using any of the class instance variables (or, in some cases, even if they were, I would pass the arguments in the method and make it static, it's easier to see what the method is doing). These methods are declared static but are also private - they are there just to avoid code duplication or to make the code easier to understand.
That being said, I don't remember running into the case where you have a class that has public static methods and that can/ should be extended. But, based on what was reported here, I would declare its static methods final.
Because static methods are the properties of the class and they are called with the name of the class rather than of object. If we make the parent class method final as well it will not be overloaded as final methods does not allow to change its memory location but we can update the final data member at the same memory location...
Related
I want to create a wrapper class that calls static methods and member fields from a class that is provided by a library I am unable to view the code.
This is to avoid boilerplate setting code of the global member fields when I need to use a static method in a specific context.
I want to try to avoid creating wrapper methods for each static method.
My question:
Is it possible to return a class with static methods from a method to access just the static methods without instantiating it?
Code is below with comments in-line.
The code is used to demonstrate a change in a static value when the method getMath() is invoked.
I want to avoid the setting of the value before calling the static method.
StaticMath.setFirstNumber(1);
StaticMath.calc(1);
StaticMath.setFirstNumber(2);
StaticMath.calc(1);
I am using the Eclipse IDE and it comes up with Warnings, which I understand, but want to avoid.
I tried searching for something on this subject, so if anyone can provide a link I can close this.
public class Demo {
// Static Methods in a class library I don't have access to.
static class StaticMath {
private static int firstNum;
private StaticMath() {
}
public static int calc(int secondNum) {
return firstNum + secondNum;
}
public static void setFirstNumber(int firstNum) {
StaticMath.firstNum = firstNum;
}
}
// Concrete Class
static class MathBook {
private int firstNum;
public MathBook(int firstNum) {
this.firstNum = firstNum;
}
// Non-static method that gets the class with the static methods.
public StaticMath getMath() {
StaticMath.setFirstNumber(firstNum);
// I don't want to instantiate the class.
return new StaticMath();
}
}
public static void main(String... args) {
MathBook m1 = new MathBook(1);
MathBook m2 = new MathBook(2);
// I want to avoid the "static-access" warning.
// Answer is 2
System.out.println(String.valueOf(m1.getMath().calc(1)));
// Answer is 3
System.out.println(String.valueOf(m2.getMath().calc(1)));
}
}
I'd just wrap it to make for an atomic operation:
public static class MyMath{
public static synchronized int myCalc( int num1 , int num2 ){
StaticMath.setFirstNum(num1);
return StaticMath.calc(num2);
}
}
Drawback: You'll have to make sure, StaticMath is not used avoiding this "bridging" class.
Usage:
int result1 = MyMath.myCalc( 1, 1 );
int result1 = MyMath.myCalc( 2, 1 );
You shouldnt call a static method through an object reference. You should directly use class reference to call a static method like this:
StaticMath.calc(1)
But if you still need it for some reason, you can return null in getMath method, but you will still get warning in Eclipse:
public StaticMath getMath() {
StaticMath.setFirstNumber(firstNum);
return null;
}
I infer that question is not properly asked if the answer is not
StaticMath.calc(1)
Other issue you may be facing due to package visibility to static inner classes. Which is a design choice by the writer of Demo class. If you can mark your classes MathBook and StaticMath public then you can access them like below:
Demo.StaticMath.calc(1);
I'm trying to write an expression or series of statements of Java source code that when written inside a static method evaluates to null, but if the method is non-static evaluates to this.
My initial idea was to 'overload' on static vs non-static, as below:
public class test {
public void method1() {
System.out.println(getThisOrNull());
}
public static void method2() {
System.out.println(getThisOrNull());
}
private static Object getThisOrNull() {
return null;
}
private Object getThisOrNull() {
return this;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
Unfortunately this isn't actually legal Java, you can't 'overload' like that and it just gives a compiler error:
test.java:14: error: method getThisOrNull() is already defined in class test
private Object getThisOrNull() {
^
1 error
Clearly in an ideal world I wouldn't write it like that to begin with, but the problem is this code will be generated automatically by a tool that is not really semantically or syntactically enough to distinguish between the static vs non-static case.
So, how can I write some source code that, although byte for byte identical compiles and behaves differently in depending on the presence of the static modifier for the method?
This can be achieved with a trick and a bit of help from Java's reflection facilities. It's ugly, but it works:
import java.lang.reflect.Field;
public class test {
public void method1() {
System.out.println(getThisOrNull(new Object(){}));
}
public static void method2() {
System.out.println(getThisOrNull(new Object(){}));
}
private static Object getThisOrNull(final Object o) {
for (Field f: o.getClass().getDeclaredFields()) {
if (f.getType().equals(test.class)) {
try {
return f.get(o);
}
catch (IllegalAccessException e) {
// Omm nom nom...
}
}
}
return null;
}
public static void main(String[] args) {
test t = new test();
System.out.println(t);
t.method1();
t.method2();
}
}
This compiles and runs as hoped for:
test#183f74d
test#183f74d
null
The trick that makes this possible is the use of new Object(){}, which creates a new, anonymous class within the existing method that we're trying to figure out if it's static or not. The behaviour of this is subtly different between the two cases.
If the goal were just to figure out if the method is static or not we could write:
java.lang.reflect.Modifiers.isStatic(new Object(){}.getClass().getEnclosingMethod().getModifiers())
Since we want to get this (when available) we need to do something slightly different. Fortunately for us classes defined within the context of an instance of an object in Java get an implicit reference to the class that contains them. (Normally you'd access it with test.this syntax). We needed a way to access test.this if it existed, except we can't actually write test.this anywhere because it too would be syntactically invalid in the static case. It does however exist within the object, as a private member variable. This means that we can find it with reflection, which is what the getThisOrNull static method does with the local anonymous type.
The downside is that we create an anonymous class in every method we use this trick and it probably adds overheads, but if you're backed into a corner and looking for a way of doing this it does at least work.
When it comes to a copy-constructor, and a lot of other cases, it makes sense, yes. But why is it allowed?
If you create a static or nonstatic Method in the class, you can manipulate the value of the variable.
public class CopyMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
TestClass tc = new TestClass(1); //val = 1
TestClass.manipulate(tc); //val = 5
TestClass.foo(tc); //print out 5
TestClass tc2 = new TestClass(tc); //tc,s val will be 6 afterwards
TestClass.foo(tc); //print out 6
}
}
class TestClass{
private int val;
public TestClass(int val){
this.val = val;
}
public TestClass(TestClass t){
this.val = t.val;
t.val = 6;
}
public static void foo(TestClass tc){
System.out.println(tc.val);
}
public static void manipulate(TestClass tc){
tc.val = 5;
}
}
The read and write of the value is written within the class (context?). But won't it hurt the access-restrictions I want with private? I'm not accessing the objects own value (like a getter/settter) but I do it to the object given with the parameter.
The reason that this access is allowed, is to allow you to implement methods such as equals and clone which have to access the private data members of another instance of the same class in order to do their job.
Example :
public Object clone ()
{
MyClass other = new MyClass ();
other.somePrivateMember = this.somePrivateMember;
...
return other;
}
Java was designed carefully (as a reaction to C++, whose worth nevertheless is high).
If you are in a class, you have those two alternatives for private:
Allow inside the class to access the private things of all instances.
Only allow access to this's private members.
So a decision only makes sense in a context of another instance.
Forbidding would mean that you would need public methods, maybe for internal, non-public operations.
Hence 1. was a logical choice to make: not exposing too much, not needing plumbing, And it is more efficient for the JVM and symmetric in coding.
It's a common practice to encapsulate code that often changes. In fact, it is often in the form of using an object to delegate the varying logic to. A sample would be the following:
public class SampleClass {
Object obj = new ObjectWithVaryingMethod();
public SampleClass(Object obj){
this.obj=obj;
}
public String getString(){
return obj.toString();
}
public static void main(String args[]){
SampleClass sampleClass=new SampleClass(new ObjectWithVaryingMethod());
System.out.println(sampleClass.getString());
}
}
class ObjectWithVaryingMethod{
#Override
public String toString(){
return "Hi";
}
}
Can you suggest what problems I may encounter when "encapsulation" is done on what doesn't vary? I find it to be a good coding conduct when the main class itself is the one that is often subject to change or improvement. A sample would be the following. In this second case, retrieving "Hi", which is the part that doesn't vary, was "encapsulated" in another class.
public class SampleVaryingClass {
public static void main(String args[]) {
//here I may opt to print getHi's value on sysout or on a dialog
System.out.println(ObjectWithNonVaryingMethod.getHi());
}
}
In a completely different class...
public class ObjectWithNonVaryingMethod {
private static final String hi = "Hi";
//"Hi" should always be returned
public static String getHi() {
return hi;
}
}
Can you give some pro's and con's on doing this?
Both code cannot be compared each other. One is static, another one isn't. I hope you understand the concept of encapsulating the object in the first code. Here is the pros and cons for the second one. Remember that static is "generally" bad, and do not support concurrency by default.
pros:
With getHi, you are keeping the string field private, meaning that it cannot be set from other source
Say that you need to do setHi from other source, you can add several guard clauses for it. This is called defensive programming.
public static setHi(String input){
if(input == null) { input = ""; } // can throw exception instead
hi = input;
}
cons:
It is static, needless to say
You don't get any advantage other than guard clauses. If your class is not static, you can swap it with other class implementing same interface, or other class inherited from that class.
I know Java basics, and now I'm in the journey of reading Effective Java. The book suggest using static factory methods instead of constructors. So I have Groovy code like this:
public class Anto {
public static void main(String[] args) {
println Java.javaInstance()
}
}
class Java {
public static Java javaInstance() {
return this
}
}
When I compile this, I get an error like this:
Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'class Java' with class 'java.lang.Class' to class 'Java'
at Java.javaInstance(Anto.groovy:9)
at Java$javaInstance.call(Unknown Source)
at Anto.main(Anto.groovy:3)
Where am I making a mistake?
You can do it using return new Java();. Static methods don't have access to this.
EDIT:
These static factories are usually singletons, which means that only one instance of the class should be used (typically, a connection to a db for example). If you want do add this dimension to your Java class, use a private static attribute as follow:
class Java {
private static Java instance;
public static Java javaInstance() {
if(instance == null) {
instance = new Java();
}
return instance;
}
}
Creating a Singleton correctly can be easy to get wrong (especially in a multi-threaded environment), so you're probably better using the Singleton annotation that comes with Groovy rather than rolling your own:
public class Anto {
public static void main(String[] args) {
println Java.instance
}
}
#Singleton
class Java {
}
This transforms the Java class to:
class Java {
private static volatile Java instance
private Java() {}
static Java getInstance () {
if( instance ) {
instance
} else {
synchronized( Java ) {
if( instance ) {
instance
} else {
instance = new Java()
}
}
}
}
}
A good (albeit not specific to Groovy) example of a library that uses static factory methods that you could look at would be Google Guava. Guava uses this idiom in a number of places. For example, their Range class supports nine types of ranges, and if they used normal constructors, their signatures would conflict in several cases since the only thing you can use to distinguish them is their arguments.
Static methods on the other hand can also be distinguished by their name, so Guava defines different ones for each type of Range. Internally these methods still call a normal constructor, but it's not one that's publicly accessible.
import com.google.common.collect.Ranges
import com.google.common.collect.DiscreteDomains
final dom = DiscreteDomains.integers()
assert [1,2,3,4,5] as Set == Ranges.closed(1, 5).asSet(dom)
assert [2,3,4] as Set == Ranges.open(1, 5).asSet(dom)
This is a useful idiom, but not one that should just be automatically preferred over a normal constructor. In situations where a normal constructor would have sufficed, you've at best written more code than you needed and at worst have made extending the class impossible, since any subclasses will still need a public or protected constructor they can call.
You can't use this because static methods are not instance methods.
Each time you create a new instance of a particular class, that new object/instance as it's own state. this points to a particular instance.
Are you trying to make a singleton ? Meaning you just want a single instance of a class ?
class Singleton {
//static reference to a particular instance
private static Singleton instance;
//private constructor so that it cant be called outside this class scope
private Singleton();
//synchronized in case your working in threaded enviroment
public synchronized static Singleton getInstance()
{
if(NULL == instance)
{
instance = new Singleton();
}
return instance;
}
}