I have a class that consists only of static member variables and static methods. Essentially, it is serving as a general-purpose utility class.
Is it bad practice for a class to contain only static member variables and static methods?
No, I don't think so at all. It is worse practice to have a class full of instance methods which don't actually depend on a particular instance. Making them static tells the user exactly how they are intended to be used. Additionally, you avoid unnecessary instantiations this way.
EDIT: As an afterthought, in general I think its nice to avoid using language features "just because", or because you think that that is the "Java way to do it". I recall my first job where I had a class full of static utility methods and one of the senior programmers told me that I wasn't fully harnessing the OO power of Java by making all of my methods "global". She was not on the team 6 months later.
As long as the class has no internal state and is essentially what is known as a leaf class (utility classes fall into this category), in other words it is independent of other classes. It is fine.
The Math class being a prime example.
Sounds reasonable.
Note: Classes that do this often have a private no-arg constructor just so that the compiler yields an error if a programmer tries to create an instance of the static class.
Static methods don't worry me much (except for testing).
In general, static members are a concern. For example, what if your app is clustered? What about start-up time -- what kind of initialization is taking place? For a consideration of these issues and more, check out this article by Gilad Bracha.
It's perfectly reasonable. In fact, in C# you can define a class with the static keyword specifically for this purpose.
Just don't get carried away with it. Notice that the java.lang.Math class is only about math functions. You might also have a StringUtilities class which contains common string-handling functions which aren't in the standard API, for example. But if your class is named Utilities, for example, that's a hint that you might want to split it up.
Note also that Java specifically introduced the static import: (http://en.wikipedia.org/wiki/Static_import)
Static import is a feature introduced
in the Java programming language that
members (fields and methods) defined
in a class as public static to be used
in Java code without specifying the
class in which the field is defined.
This feature was introduced into the
language in version 5.0.
The feature provides a typesafe
mechanism to include constants into
code without having to reference the
class that originally defined the
field. It also helps to deprecate the
practice of creating a constant
interface: an interface that only
defines constants then writing a class
implementing that interface, which is
considered an inappropriate use of
interfaces[1].
The mechanism can be used to reference
individual members of a class:
import static java.lang.Math.PI;
import static java.lang.Math.pow;
or all the static members of a class:
import static java.lang.Math.*;
While I agree with the sentiment that it sounds like a reasonable solution (as others have already stated), one thing you may want to consider is, from a design standpoint, why do you have a class just for "utility" purposes. Are those functionals truly general across the entire system, or are they really related to some specific class of objects within your architecture.
As long as you have thought about that, I see no problem with your solution.
The Collections class in Java SDK has static members only.
So, there you go, as long as you have proper justification -- its not a bad design
Utility methods are often placed in classes with only static methods (like StringUtils.) Global constants are also placed in their own class so that they can be imported by the rest of the code (public final static attributes.)
Both uses are quite common and have private default constructors to prevent them from being instantiated. Declaring the class final prevents the mistake of trying to override static methods.
If by static member variables you did not mean global constants, you might want to place the methods accessing those variables in a class of their own. In that case, could you eleborate on what those variables do in your code?
This is typically how utility classes are designed and there is nothing wrong about it. Famous examples include o.a.c.l.StringUtils, o.a.c.d.DbUtils, o.s.w.b.ServletRequestUtils, etc.
According to a rigid interpretation of Object Oriented Design, a utility class is something to be avoided.
The problem is that if you follow a rigid interpretation then you would need to force your class into some sort object in order to accomplish many things.
Even the Java designers make utility classes (java.lang.Math comes to mind)
Your options are:
double distance = Math.sqrt(x*x + y*y); //using static utility class
vs:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
Even if we were to avoid the verbose method, we could still end up with:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
in this instance, .sqrt() is still static, so what would the point be in creating the object in the first place?
The answer is, create utility classes when your other option would be to create some sort of artificial "Worker" class that has no or little use for instance variables.
This link http://java.dzone.com/articles/why-static-bad-and-how-avoid seems to go against most of the answers here. Even if it contains no member variables (i.e. no state), a static class can still be a bad idea because it cannot be mocked or extended (subclassed), so it is defeating some of the principles of OO
I wouldn't be concerned over a utility class containing static methods.
However, static members are essentially global data and should be avoided. They may be acceptable if they are used for caching results of the static methods and such, but if they are used as "real" data that may lead to all kinds of problems, such as hidden dependencies and difficulties to set up tests.
From TSLint’s docs:
Users who come from a Java-style OO language may wrap their utility functions in an extra class, instead of putting them at the top level.
The best way is to use a constant, like this:
export const Util = {
print (data: string): void {
console.log(data)
}
}
Examples of incorrect code for this rule:
class EmptyClass {}
class ConstructorOnly {
constructor() {
foo();
}
}
// Use an object instead:
class StaticOnly {
static version = 42;
static hello() {
console.log('Hello, world!');
}
}
Examples of correct code for this rule:
class EmptyClass extends SuperClass {}
class ParameterProperties {
constructor(public name: string) {}
}
const StaticOnly = {
version: 42,
hello() {
console.log('Hello, world!');
},
};
I need to use getString() from most of the modules in my application.
But for some strange reason, it is tied to Application or Context, so that means I need to pass to each and every class in my application, the Application reference as a parameter.
This clearly violates one of the most basic principles of object oriented design.
Is there a way around this?
The 'strange reason' is that since the string resources are tied to your application, there is no way to access them without some sort of handle to it (the Context). If most of your classes that are not activities need to access string resources, you might want to rethink your design a bit. A simple way to not depend on a Context is to load the strings and pass them to your classes in the constructor.
Yes, there is a workaround - if you happen to (or can) pass a View (any View-derived class) to the constructor, and you assign it to a data member, then you can access the string resources from anywhere in your class:
String str_via_res = yourView.getContext().getString(R.string.str_via_res);
Otherwise, you will have to pass a Context to every class that needs access to these string resources.
you can extend android.app.Application class to create a static method to pass on the context across all classes in your application.
Refer : PhoneApp.java
I got a doubt regarding the content provider.
Everytime when i am write the content provider, i am placing the URI MATCHER definition in the static brackets but the URI MATCHER is declared a private data member of the class. Only definition(new UriMatcher) is being placed in the static brackets.
Will anyone please let me know the reason. I tried googling but not able to find the answer. Me too will try please let me know if anyone knows already.
Thanks & Regards,
SSuman185
It is a static initialization block.
When you define a member or class variable the value must fit on a single line (even if you space it over more), and it cannot include complicated logic.
For member variables you can do this complicated initialization in the Constructor.
Essentially a static initialization block is a constructor for your class variables, allowing you to use more complicated expressions when initializing. It is only executed once, when the class is first loaded, no matter how many instances are created.
A private member just means the variable is not accessible to other classes, it is still accessible to the class itself. So the static initialization block only creates the URIMatcher once (when the class is loaded), no matter how many instances there are.
I want to define constants which can be used by all activities in an application. What is the best way to do it.
Is extends Application only way of doing it, since I dont want to declare same constant in all the classes.
There are two ways I've used that are effective:
1) Make an interface called Constants or Globals or whatever you want. Define your constant values in that class and make them all public and final. (They have to be public by definition of an interface, but be sure they're final as well). Now simply declare your Activities and any other classes to implement your Constants interface. Now they all have access to the same global values.
2) Make a class Constants instead of an interface. Define all your constants as public static final. Now you can reference all your constant values via Constants.VARIABLE_NAME in any class in your application.
Simple answer declare that Variable as STATIC FINAL and use that constant in all activity's by the name of you activity.constantname eg:activity1.name
it will take same values whenever you use it, also it will change globally.. takes same values no matters from which Activity you are accessing It.
I would use a class holding those values as static and set / get them with static methods.
If you want to assign all Activities to a Constant you declared by Creating Constant Class then,
Enter this Lines to your Constants class:
public static Class_Name Constant_name = null;
and in the Activities, add this line into onCreate() method:
Class_Name Constant_name = this;
I have 2 BroadcastReceivers in my android application. They are in the same package.
If in the onReceive() method, they both read/write a static class variable (in a separate Util class). Does android create 1 copy of that static class variable or 2 (1 for each receiver)?
And what do I need to do to make sure they are accessing the static class variable not corrupting the data?
There will only be one instance of the static variable. From http://download.oracle.com/javase/tutorial/java/javaOO/classvars.html:
A class variable is any field declared
with the static modifier; this tells
the compiler that there is exactly one
copy of this variable in existence,
regardless of how many times the class
has been instantiated.
To avoid problems, you will have to make sure the static variable is thread safe. Some data structures, like Vector, are already thread safe, so you would not have to do anything further. Otherwise, you may have to use the synchronized keyword or something from the java.util.concurrent.locks package.
Don't use static variables, make the class Singleton.
"And what do I need to do to make sure they are accessing the static class variable not corrupting the data?" - add synchronized to getters/setters