This question already has answers here:
class or method alias in java
(8 answers)
Closed 3 years ago.
I have a class with a probably unnecessarily cumbersome name, that contains a lot of static methods I use elsewhere.
Rather than fill my code with a lot of
VeryUnnecessarilyLongCumbersomeName.doThingFoo();
VeryUnnecessarilyLongCumbersomeName.doThingBar();
VeryUnnecessarilyLongCumbersomeName.doThingEgg();
VeryUnnecessarilyLongCumbersomeName.doThingSpam();
I would rather have
VeryUnnecessarilyLongCumbersomeName thing = new VeryUnnecessarilyLongCumbersomeName();
thing.doThingFoo();
thing.doThingBar();
thing.doThingEgg();
thing.doThingSpam();
However, this gets the warning
"the static method doThingFoo() should be accessed in a static way."
I know there are multiple solutions here. Use better class names. Make it not static. Ignore it because it's just a warning.
But I don't actually think it should be a warning. What harm does doing it this way cause? Is there a more elegant/correct way to make my code less clunky that isn't one of the above solutions?
NOTE: I suspect this might warrant the coding-style tag and therefore be considered off-topic and get rejected. I was thinking there's room here for a question like this, however, so I leave it up to y'all.
Although it is not technically harmful because it technically works, the problem with this is it is misleading, and any values that the instance thing contains, do not actually matter at all for the results of the methods.
Typical Java Convention:
When accessing a method through an instance, one would expect the result to be dependent on the values of the instance.
When accessing a method through a Class name, one would expect the result to be independent of the values of any instance.
Your way:
You are accessing a method through an instance and expecting it to be independent of any instance.
So why use an instance for an instance independent method? That is why it is misleading. I would suggest attempting to shorten the class name rather than accessing static methods through an instance.
How about changing the VeryUnnecessarilyLongCumbersomeName class?
Static methods are there to be used without instances. They are meant to be used if you want to invoke the method without first initializing a class. The downside of using static methods is that you lose all kinds of OOP benefits; You lose virtual dispatch and subsequently polymorphism. You can never override that method in a derived class. Of course you can declare a new (static) method in a derived class, but any code that accesses it has to be aware of the entire class hierarchy and do explicit checking and casting, which is precisely what OO is supposed to avoid.
Also, it is confusing. When another programmer sees your code, he/she will think upon seeing a static he/she will assume that it will not require a valid instance to invoke the method.
TLDR; don't do it and stick with the best practices =)
Related
By making private constructor, we can avoid instantiating class from anywhere outside. and by making class final, no other class can extend it. Why is it necessary for Util class to have private constructor and final class ?
This is not a mandate from a functional point of view or java complication or runtime. However, it's a coding standard accepted by the wider community. Even most static code review tools, like checkstyle, check that such classes have this convention followed.
Why this convention is followed is already explained in other answers and even OP covered that, but I'd like to explain it a little further.
Mostly utility classes are a collection of methods/functions which are independent of an object instance. Those are kind of like aggregate functions as they depend only on parameters for return values and are not associated with class variables of the utility class. So, these functions/methods are mostly kept static. As a result, utility classes are, ideally, classes with only static methods. Therefore, any programmer calling these methods doesn't need to instantiate the class. However, some robo-coders (maybe with less experience or interest) will tend to create the object as they believe they need to before calling its method. To avoid that, we have 3 options:
Keep educating people to not instantiate it. (No sane person can keep doing it.)
Mark the utility class as abstract: Now robo-coders will not create the object. However, reviewers and the wider java community will argue that marking the class as abstract means you want someone to extend it. So, this is also not a good option.
Private constructor: Not protected because it'll allow a child class to instantiate the object.
Now, if someone wants to add a new method for some functionality to the utility class, they don't need to extend it: they can add a new method as each method is independent and has no chance of breaking other functionalities. So, no need to override it. Also, you are not going to instantiate it, so no need to subclass it. Better to mark it final.
In summary, instantiating a utility class (new MyUtilityClass()) does not make sense. Hence the constructors should be private. And you never want to override or extend it, so mark it final.
It's not necessary, but it is convenient. A utility class is just a namespace holder of related functions and is not meant to be instantiated or subclassed. So preventing instantiation and extension sends a correct message to the user of the class.
There is an important distinction between the Java Language, and the Java Runtime.
When the java class is compiled to bytecode, there is no concept of access restriction, public, package, protected, private are equivalent. It is always possible via reflection or bytecode manipulation to invoke the private constructor, so the jvm cannot rely on that ability.
final on the other hand, is something that persists through to the bytecode, and the guarantees it provides can be used by javac to generate more efficient bytecode, and by the jvm to generate more efficient machine instructions.
Most of the optimisations this enabled are no longer relevant, as the jvm now applies the same optimisations to all classes that are monomorphic at runtime—and these were always the most important.
By default this kind of class normally is used to aggregate functions who do different this, in that case we didn't need to create a new object
This question already has answers here:
What is the point of "final class" in Java?
(24 answers)
Closed 9 years ago.
I was asked about the reason of why a final class cannot be overridden. I tried to explain that it is more of design approach where by you don't want your class to be extended or methods to be overridden and a final class also helps to make an object immutable (though there are more steps to be done rather than just declaring the class as final).
However I would like to know if there is more to thought process behind declaring a class as final or the fact that it cannot be overridden?
Because them's the rules; It's a part of the design of the language.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.1.2
As a designer you say "my class is not suitable for inheritence"; Java honours this by explicitly preventing someone from doing so.
Final class cannot be extended because Java compiler will not allow it, because Java compiler follows the rules defined by Java Language Specification which does not allow it.
final methods can't be overriden, because that's what final is designed to do: it's a sign saying "do not override this".
From Wiki
A final method cannot be overridden or hidden by subclasses. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.
A common misconception is that declaring a class or method as final improves efficiency by allowing the compiler to directly insert the method wherever it is called (see inline expansion). But because the method is loaded at runtime, compilers are unable to do this. Only the runtime environment and JIT compiler know exactly which classes have been loaded, and so only they are able to make decisions about when to inline, whether or not the method is final.
A final class is a class that can't be extended, thats the reason u cannot override the final class
it is also used to make the class immutable
and one good advantage of defining class as final that it improves JVM performance
see this
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Private vs. Public members in practice (how important is encapsulation?)
Recently I've been coming across a situation where I declare a class variable as public, because it will be used in another class. Someone told me recently that I should make such variables private and write a public method returning the value of the variable. I was told this was good practice. I searched through my Java book and couldnt find any reference to this. My question is, is it good practice to declare as many as possible class variables as private?
Yes. Generally, all variables should be private (not protected, private), and there should be methods to get their values (and possibly set them) if (and only if) you want to allow that by outsiders. The variables you use are an implementation detail, and usually contain data that has to be a certain way. Getters and setters allow you to take responsibility for that data, validate it, synchronize it, etc, instead of letting some jackass store random stuff in it and potentially make your object unusable.
The sole exception might be classes whose only purpose is storage of data so you can ship it around as one object, kinda like a C/C++ struct. But then, you're making a decision that no, you don't want to validate, synchonize, encapsulate that data in any way...and changing your mind later breaks binary compatibility (meaning any code that touched that class will need to be recompiled). Not a big deal in a little private project; huge deal in a public framework/API.
I'm learning Java (and OOP) and although it might irrelevant for where I'm at right now, I was wondering if SO could share some common pitfalls or good design practices.
One important thing to remember is that static methods cannot be overridden by a subclass. References to a static method in your code essentially tie it to that implementation. When using instance methods, behavior can be varied based on the type of the instance. You can take advantage of polymorphism. Static methods are more suited to utilitarian types of operations where the behavior is set in stone. Things like base 64 encoding or calculating a checksum for instance.
I don't think any of the answers get to the heart of the OO reason of when to choose one or the other. Sure, use an instance method when you need to deal with instance members, but you could make all of your members public and then code a static method that takes in an instance of the class as an argument. Hello C.
You need to think about the messages the object you are designing responds to. Those will always be your instance methods. If you think about your objects this way, you'll almost never have static methods. Static members are ok in certain circumstances.
Notable exceptions that come to mind are the Factory Method and Singleton (use sparingly) patterns. Exercise caution when you are tempted to write a "helper" class, for from there, it is a slippery slope into procedural programming.
If the implementation of a method can be expressed completely in terms of the public interface (without downcasting) of your class, then it may be a good candidate for a static "utility" method. This allows you to maintain a minimal interface while still providing the convenience methods that clients of the code may use a lot. As Scott Meyers explains, this approach encourages encapsulation by minimizing the amount of code impacted by a change to the internal implementation of a class. Here's another interesting article by Herb Sutter picking apart std::basic_string deciding what methods should be members and what shouldn't.
In a language like Java or C++, I'll admit that the static methods make the code less elegant so there's still a tradeoff. In C#, extension methods can give you the best of both worlds.
If the operation will need to be overridden by a sub-class for some reason, then of course it must be an instance method in which case you'll need to think about all the factors that go into designing a class for inheritance.
My rule of thumb is: if the method performs anything related to a specific instance of a class, regardless of whether it needs to use class instance variables. If you can consider a situation where you might need to use a certain method without necessarily referring to an instance of the class, then the method should definitely be static (class). If this method also happens to need to make use of instance variables in certain cases, then it is probably best to create a separate instance method that calls the static method and passes the instance variables. Performance-wise I believe there is negligible difference (at least in .NET, though I would imagine it would be very similar for Java).
If you keep state ( a value ) of an object and the method is used to access, or modify the state then you should use an instance method.
Even if the method does not alter the state ( an utility function ) I would recommend you to use an instance method. Mostly because this way you can have a subclass that perform a different action.
For the rest you could use an static method.
:)
This thread looks relevant: Method can be made static, but should it? The difference's between C# and Java won't impact its relevance (I think).
Your default choice should be an instance method.
If it uses an instance variable it must be an instance method.
If not, it's up to you, but if you find yourself with a lot of static methods and/or static non-final variables, you probably want to extract all the static stuff into a new class instance. (A bunch of static methods and members is a singleton, but a really annoying one, having a real singleton object would be better--a regular object that there happens to be one of, the best!).
Basically, the rule of thumb is if it uses any data specific to the object, instance. So Math.max is static but BigInteger.bitCount() is instance. It obviously gets more complicated as your domain model does, and there are border-line cases, but the general idea is simple.
I would use an instance method by default. The advantage is that behavior can be overridden in a subclass or if you are coding against interfaces, an alternative implementation of the collaborator can be used. This is really useful for flexibility in testing code.
Static references are baked into your implementation and can't change. I find static useful for short utility methods. If the contents of your static method are very large, you may want to think about breaking responsibility into one or more separate objects and letting those collaborate with the client code as object instances.
IMHO, if you can make it a static method (without having to change it structure) then make it a static method. It is faster, and simpler.
If you know you will want to override the method, I suggest you write a unit test where you actually do this and so it is no longer appropriate to make it static. If that sounds like too much hard work, then don't make it an instance method.
Generally, You shouldn't add functionality as soon as you imagine a use one day (that way madness lies), you should only add functionality you know you actually need.
For a longer explanation...
http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It
http://c2.com/xp/YouArentGonnaNeedIt.html
the issue with static methods is that you are breaking one of the core Object Oriented principles as you are coupled to an implementation. You want to support the open close principle and have your class implement an interface that describes the dependency (in a behavioral abstract sense) and then have your classes depend on that innterface. Much easier to extend after that point going forward . ..
My static methods are always one of the following:
Private "helper" methods that evaluate a formula useful only to that class.
Factory methods (Foo.getInstance() etc.)
In a "utility" class that is final, has a private constructor and contains nothing other than public static methods (e.g. com.google.common.collect.Maps)
I will not make a method static just because it does not refer to any instance variables.
I was thinking how much code one should put in constructors in Java? I mean, very often you make helper methods, which you invoke in a constructor, but sometimes there are some longer initialization things, for example for a program, which reads from a file, or user interfaces, or other programs, in which you don't initialize only the instance variables, in which the constructor may get longer (if you don't use helper methods). I have something in mind that the constructors should generally be short and concise, shouldn't they? Are there exceptions to this?
If you go by the SOLID principles, each class should have one reason to change (i.e. do one thing). Therefore a constructor would normally not be reading a file, but you would have a separate class that builds the objects from the file.
Take a look at this SO question. Even though the other one is for C++, the concepts are still very similar.
As little as is needed to complete the initialization of the object.
If you can talk about a portion (5 or so lines is my guideline) of your constructor as a chunk of logic or a specific process, it's probably best to split it into a separate method for clarity and organizational purposes.
But to each his own.
My customary practice is that if all the constructor has to do is set some fields on an object, it can be arbitrarily long. If it gets too long, it means that the class design is broken anyway, or data need to be packaged in some more complex structures.
If, on the other hand, the input data need some more complex processing before initializing the class fields, I tend to give the constructor the processed data and move the processing to a static factory method.
Constructors should be just long enough, but no longer =)
If you are defining multiple overloaded constructors, don't duplicate code; instead, consolidate functionality into one of them for improved clarity and ease of maintenance.
As Knuth said, "Premature optimization is the root of all evil."
How much should you put in the consructor? Everything you need to. This is the "eager" approach. When--and only when--performance becomes an issue do you consider optimizing it (to the "lazy" or "over-eager" approaches).
Constructors should create the most minimal, generic instance of your object. How generic? Choose the test cases that every instance or object that inherits from the class must pass to be valid - even if "valid" only means fails gracefully (programatically generated exception).
Wikipedia has a good description :
http://en.wikipedia.org/wiki/Constructor_(computer_science)
A Valid object is the goal of the constructor, valid not necessarily useful - that can be done in an initialization method.
Your class may need to be initialized to a certain state, before any useful work can be done with it.
Consider this.
public class CustomerRecord
{
private Date dateOfBirth;
public CustomerRecord()
{
dateOfBirth = new Date();
}
public int getYearOfBirth()
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateOfBirth);
return calendar.get(Calendar.YEAR);
}
}
Now if you don't initialize the dateOfBirth member varialble, any subsequent invocation of getYearOfBirth(), will result in a NullPointerException.
So the bare minimum initialization which may involve
Assigning of values.
Invoking helper functions.
to ensure that the class behaves correctly when it's members are invoked later on, is all that needs to be done.
Constructor is like an Application Setup Wizard where you do only configuration. If the Instance is ready to take any (possible) Action on itself then Constructor doing well.