Java why static is bad

Why using static in Java is bad?

The reason you are warned away from static methods is that using them forfeits one of the advantages of objects. Objects are intended for data encapsulation. This prevents unexpected side effects from happening which avoids bugs. Static methods have no encapsulated data* and so don’t garner this benefit.

What is the disadvantage of static method in Java?

Disadvantages: Static members are part of class and thus remain in memory till application terminates and can’t be ever garbage collected. Using excess of static members sometime predicts that you fail to design your product and trying to cop of with static / procedural programming.

Is it good to use static variables in Java?

When you want to have a variable that always has the same value for every object of the class, forever and ever, make it static . If you have a method that does not use any instance variables or instance methods, you should probably make it static .

Is it good to have static methods?

Static methods are bad for testability.

Читайте также:  Javascript event return value

Since static methods belong to the class and not a particular instance, mocking them becomes difficult and dangerous.

Are static methods faster?

They are faster — Static methods are slightly faster than instance methods because in instance methods, you are also working with an implicit this parameter. Eliminating that parameter gives a slight performance boost in most programming languages.

Can we override static method?

Static methods cannot be overridden because they are not dispatched on the object instance at runtime. The compiler decides which method gets called. Static methods can be overloaded (meaning that you can have the same method name for several methods as long as they have different parameter types).

What is the benefit of having static field?

Essentially, static methods let you write procedural code in an object oriented language. It lets you call methods without having to create an object first. The only time you want to use a static method in a class is when a given method does not require an instance of a class to be created.

Is static class bad?

The abuse of static classes can be considered bad practice. But so can the abuse of any language feature. I make no distinction between a non-static class with only static methods and a static class.

What are the restrictions of static method?

Restrictions on static blocks and static methods

  • You cannot access a non-static member (method or, variable) from a static context.
  • This and super cannot be used in static context.
  • The static method can access only static type data (static type instance variable).
  • You cannot override a static method.

Is overriding possible in Java?

In Java, methods are virtual by default. We can have multilevel method-overriding. Overriding vs Overloading : … Overriding is about same method, same signature but different classes connected through inheritance.

What is the benefit of static keyword in Java?

In Java, static keyword is mainly used for memory management. It can be used with variables, methods, blocks and nested classes. It is a keyword which is used to share the same variable or method of a given class. Basically, static is used for a constant variable or a method that is same for every instance of a class.

About me

Hey! My name is Ken and this is my blog about web programming languages, how to understand them and how to use them. This is my first blog on programming languages. Here I post useful information and answers to frequently asked questions from novice programmers.

ATTENTION TO RIGHT HOLDERS! All materials are posted on the site strictly for informational and educational purposes! If you believe that the posting of any material infringes your copyright, be sure to contact us through the contact form and your material will be removed!

Источник

fritzthecat-blog

In this article I’d like to argue about the Java static keyword. Static is an access modifier that binds a field or method to its class instead of its object instance. It has become an unpleasant obsession to use statics, because implementing with globals is much easier than to follow the object-oriented idea of small, comprehensible and controllable scopes. Java is OO, and we should not let us throw back to structured programming as done with old languages like C.

Mind that the static keyword on inner classes has a complete different semantic. It’s not bad, it’s actually good. It makes the instances of the inner class independent of the outer class instance, because they don’t have a (hidden) reference to the outer object. The garbage collector will be able to easily collect such instances, whereby it never could collect instances of non-static inner classes as long as the outer instance is still in use.

I won’t discuss static fields. Anybody that used Java for some years will tell you that you should not use static non-final fields. Always make them final. Read these quotes from Stackoverflow:

Quotes

You cannot override static methods. They don’t participate in runtime polymorphism. Interfaces and abstract classes only define non-static methods. Static methods thus don’t fit very well into inheritance. Statics have a lifetime that matches the entire runtime of the program. The memory consumed by all those static variables can never be garbage collected. In object-oriented programming, each object has its own state, represented by non-static instance variables. Static variables, on the other hand, represent state across instances which can be much more difficult to unit-test. Statics can’t be easily mocked. Since all statics fields live in just one space, all threads wishing to use them must go through a slow synchronization control that you have to implement on each of them. Static fields wouldn’t be serialized. The tighter the scope of something, the easier it is to reason about. We’re good at thinking about small things, but it’s hard to reason about the state of a system made from millions lines of code. Statics tend to produce spaghetti code and don’t easily allow refactoring or testing.

Override Example

Following example shows that code in static methods can not be overridden.

public class PrintUtil  public static void print(String text)  final String printText = "["+text+"]"; System.out.println(printText); > > 
public class CustomPrintUtil extends PrintUtil  public static void print(String text)  final String printText = ">"+text+"; System.err.println(printText); > > 
public class Main  public static void main(String[] arguments)  PrintUtil printUtil = new CustomPrintUtil(); printUtil.print("Hello World"); > > 

Output of Main.main() is, on System.out:

Expected was, on System.err:

Reason is that main() assigned the new object to a variable typed as PrintUtil . Had it been CustomPrintUtil , it would have worked as expected, but — who can control that?

Constructor Class Example

Important to understand: constructor calls are static references, although there is no static keyword anywhere!

This example shows that it is impossible to replace class Line by IndentedLine inside the MultilineText class, because there is a static class reference, i.e. a constructor call with the new operator, that has not been put into an overridable factory method.

Here is the element class Line :

public class Line  private final String text; public Line(String text)  this.text = text; > public void output(PrintStream printStream)  printStream.println(text); > > 

It lives inside MultilineText :

public class MultilineText  private final ListLine> lines = new ArrayList<>(); public void addLine(String line)  lines.add(new Line(line)); > public IterableLine> lines()  return Collections.unmodifiableList(lines); > > 

There is no static modifier anywhere, but the new Line() constructor call in line 6 must be seen as static class reference, basically it is the same as a static LineFactory.create() call:

public final class LineFactory  public static Line create(String text)  return new Line(line); > > 
. public void addLine(String line)  lines.add(LineFactory.create(line)); > . 

Here comes the IndentedLine class that we would like to have inside the MultilineText class:

public class IndentedLine extends Line  public IndentedLine(String text)  super(text); > @Override public void output(PrintStream printStream)  printStream.print("\t"); super.output(printStream); > > 

The following procedure tries to replace Line inside MultilineText with an anonymous class override:

MultilineText multilineText = new MultilineText()  @Override public void addLine(String line)  lines.add(new IndentedLine(line)); //  // . because lines is private! > >; multilineText.addLine("Hello World!"); multilineText.addLine("Goodbye World!"); for (Line line : multilineText.lines()) line.output(System.out); 

The override of the addLine() method causes a compile error because the private lines list is not accessible for sub-classes. If it was protected , sub-classes could access it, but also corrupt it.

How to fix that? Break encapsulation and make line-list protected ? I know a better solution:

public class MultilineText  private final ListLine> lines = new ArrayList<>(); public void addLine(String line)  lines.add(createLine(line)); > protected Line createLine(String line)  return new Line(line); > public IterableLine> lines()  return Collections.unmodifiableList(lines); > > 

We encapsulated the Line constructor into an overridable factory-method protected Line createLine() . Now we can easily override the factory method and generate another type of Line :

MultilineText multilineText = new MultilineText()  @Override public Line createLine(String line)  return new IndentedLine(line)); > >; multilineText.addLine("Hello World!"); multilineText.addLine("Goodbye World!"); for (Line line : multilineText.lines()) line.output(System.out); 
Hello World! Goodbye World!

Mind what a powerful techique factory methods are: we can override/customize not just a certain class but a whole class graph by embedding further anonymous overrides!

Conclusion

It is really hard to give a convincing proof that static methods, or constructor calls without factory-method, are a bad practice. They are so frequent, everybody uses them.

Historically seen, using static is a technical throwback of 30 years. Code inside static methods is not overridable, and only reusable when all mutable state is given as parameters, in other words, when it is a «pure function».

The Spring framework tried to solve the problem of statics and globals. You should not use the Spring context as global static space, moreover you should have one context per class-graph (component, module). Then apply dependency injection wherever you are tempted to use the static keyword.

The object-oriented vision is that we solve problems using object graphs that wrap any new operator or static call into a protected overridable (non-final) factory-method. Such graphs are then fully customizable and thus reusable frameworks. One such graph can represent a component (or Java 9 JPMS-module), and components can be bound together at runtime over their interfaces using service loading or dependency injection. JPMS modules support service declarations.

Источник

Оцените статью