In Java, is there any disadvantage to static methods on a class?

后端 未结 14 1418
无人及你
无人及你 2020-12-03 06:37

Lets assume that a rule (or rule of thumb, anyway), has been imposed in my coding environment that any method on a class that doesn\'t use, modify, or otherwise need any ins

相关标签:
14条回答
  • 2020-12-03 07:14

    The main disadvantage is that you cannot swap, override or choose method implementations at runtime.

    0 讨论(0)
  • 2020-12-03 07:15

    Disadvantage -> 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. It denotes that object oriented design is compromised.This can result in memory over flow.

    0 讨论(0)
  • 2020-12-03 07:20

    In general:

    You should be writing your software to take advantage of interfaces and not implementations. Who's to say that "now" you won't use some instance variable, but in the future you will? An example of coding to interfaces...

    ArrayList badList = new ArrayList();  //bad
    List goodList = new ArrayList();  //good
    

    You should be allowed to swap implementations, especially for mocking & testing. Spring dependency injection is pretty nice in this respect. Just inject the implementation from Spring and bingo you have pretty much a "static" (well, singleton) method...

    Now, those types of APIs that are purely "utility" in purpose (i.e., Apache Commons Lang) are the exception here because I believe that most (if not all) of the implementations are static. In this situation, what are the odds that you will want to ever swap Apache Commons out for another API?

    Specifically:

    How would you elegantly handle the "staticness" of your implementation when you're targeting, say, a Websphere vs. Tomcat deployment? I'm sure there would be an instance (no pun intended) of when your implementation would differ between the two...and relying on a static method in one of those specific implementations might be dangerous...

    0 讨论(0)
  • 2020-12-03 07:21

    It's all a question of context. Some people have already given examples where static is absolutely preferable, such as when writing utility functions with no conceivable state. For example, if you are writing a collection of different sort algorithms to be used on arrays, making your method anything but static just confuses the situation. Any programmer reading your code would have to ask, why did you NOT make it static, and would have to look to see if you are doing something stateful to the object.

    public class Sorting {
      public static void quiksort(int [] array) {}
      public static void heapsort(int[] array) { }
    }
    

    Having said that, there are many people who write code of some kind, and insist that they have some special one-off code, only to find later that it isn't so. For example, you want to calculate statistics on a variable. So you write:

    public class Stats {
      public static void printStats(float[] data) { }
    }
    

    The first element of bad design here is that the programmer intends to just print out the results, rather than generically use them. Embedding I/O in computation is terrible for reuse. However, the next problem is that this general purpose routine should be computing max, min, mean, variance, etc. and storing it somewhere. Where? In the state of an object. If it were really a one-off, you could make it static, but of course, you are going to find that you want to compute the mean of two different things, and then it's awfully nice if you can just instantiate the object multiple times.

    public class Stats {
      private double min,max,mean,var;
      public void compute(float data[]) { ... }
      public double getMin() { return min; }
      public double
    }
    

    The knee jerk reaction against static is often the reaction of programmers to the stupidity of doing this sort of thing statically, since it's easier to just say never do that than actually explain which cases are ok, and which are stupid.

    Note that in this case, I am actually using the object as a kind of special-purpose pass by reference, because Java is so obnoxious in that regard. In C++, this sort of thing could have been a function, with whatever state passed as references. But even in C++, the same rules apply, it's just that Java forces us to use objects more because of the lack of pass by reference.

    As far as performance goes, the biggest performance increase of switching from a regular method is actually avoiding the dynamic polymorphic check which is the default in java, and which in C++ is specified manually with virtual.

    When I tried last there was a 3:1 advantage of calling a final method over a regular method, but no discernible for calling static functions over final.

    Note that if you call one method from another, the JIT is often smart enough to inline the code, in which case there is no call at all, which is why making any statement about exactly how much you save is extremely dangerous. All you can say is that when the compiler has to call a function, it can't hurt if it can call one like static or final which requires less computation.

    0 讨论(0)
  • 2020-12-03 07:21

    The main problem you may face is, you won't be able to provide a new implementation if needed.

    If you still have doubts ( whether your implementation may change in the future or not ) you can always use a private instance underneath with the actual implementation:

     class StringUtil {
         private static StringUtil impl = new DefaultStringUtil();
    
         public static String nullOrValue( String s ) {
              return impl.doNullOrValue();
         }
         ... rest omitted 
      }
    

    If for "some" reason, you need to change the implementation class you may offer:

      class StringUtil {
         private static StringUtil impl = new ExoticStringUtil();
    
         public static String nullOrValue( String s ) {
              return impl.doNullOrValue(s);
         }
         ... rest omitted 
      }
    

    But may be excessive in some circumstances.

    0 讨论(0)
  • 2020-12-03 07:23

    There shouldn't be any disadvantages--there may even be a slight advantage in performance (although it wouldn't be measurable) since the dynamic lookup can be avoided.

    It's nice to tag functions as functions instead of having them look like Methods--(and static "Methods" ARE functions, not methods--that's actually by definition).

    In general a static method is a bad OO code smell--it probably means that your OO model isn't fully integrated. This happens all the time with libraries that can't know about the code that will be using it, but in integrated non-library code static methods should be examined to evaluate which of it's parameters it's most closely associated with--there is a good chance it should be a member of that class.

    If a static method just takes native values, then you're probably missing a handful of classes; you should also keep passing native variables or library objects (like collections) to a minimum--instead containing them in classes with business logic.

    I guess what I'm saying is that if this is really an issue, you might want to re-examine your modeling practices--statics should be so rare that this isn't even an issue.

    0 讨论(0)
提交回复
热议问题