Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names. The important points to note here: Use it when you require frequent access to static members from one or two classes. Used appropriately, static import can make your program more readable.
For utility or helper methods that don't require any object state. Since there is no need to access instance variables, having static methods eliminates the need for the caller to instantiate the object just to call the method. For the state that is shared by all instances of the class, like a counter.
by Joshua Bloch.) This is considered bad Java programming practice because when a class implements an interface, it becomes part of the class's public API. Implementation details, such as using the static members of another class, should not leak into public APIs.
static import allows to access the static members of a class without class qualifications. For Example, to access the static methods you need to call the using class name: Math. sqrt(169);
This is from Sun's guide when they released the feature (emphasis in original):
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). ... If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. Readers of your code (including you, a few months after you wrote it) will not know which class a static member comes from. Importing all of the static members from a class can be particularly harmful to readability; if you need only one or two members, import them individually.
(https://docs.oracle.com/javase/8/docs/technotes/guides/language/static-import.html)
There are two parts I want to call out specifically:
extend some.package.DA
? If so, static imports may be a cleaner way of handling this. If you never would have dreamed of extending some.package.DA
, then this is probably a poor use of static imports. Don't use it just to save a few characters when typing.import static some.package.DA.save
instead of DA.*
. That will make it much easier to find where this imported method is coming from. Personally, I have used this language feature very rarely, and almost always only with constants or enums, never with methods. The trade-off, for me, is almost never worth it.
Another reasonable use for static imports is with JUnit 4. In earlier versions of JUnit methods like assertEquals
and fail
were inherited since the test class extended junit.framework.TestCase
.
// old way
import junit.framework.TestCase;
public class MyTestClass extends TestCase {
public void myMethodTest() {
assertEquals("foo", "bar");
}
}
In JUnit 4, test classes no longer need to extend TestCase
and can instead use annotations. You can then statically import the assert methods from org.junit.Assert
:
// new way
import static org.junit.Assert.assertEquals;
public class MyTestClass {
@Test public void myMethodTest() {
assertEquals("foo", "bar");
// instead of
Assert.assertEquals("foo", "bar");
}
}
JUnit documents using it this way.
Effective Java, Second Edition, at the end of Item 19 notes that you can use static imports if you find yourself heavily using constants from a utility class. I think this principle would apply to static imports of both constants and methods.
import static com.example.UtilityClassWithFrequentlyUsedMethods.myMethod;
public class MyClass {
public void doSomething() {
int foo = UtilityClassWithFrequentlyUsedMethods.myMethod();
// Can be written less verbosely as
int bar = myMethod();
}
}
This has advantages and disadvantages. It makes the code a bit more readable at the expense of losing some immediate information about where the method is defined. However, a good IDE will let you go to the definition, so this isn't much of an issue.
You should still use this sparingly, and only if you find yourself using things from the imported file many, many times.
Edit: Updated to be more specific to methods, as that's what this question is referring to. The principle applies regardless of what's being imported (constants or methods).
I think static import is really useful to remove redundant class names when using utils classes like Arrays
and Assertions
.
Not sure why but Ross skipped out the last sentence that mentions this in the documentation he is referencing.
Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.
Basically copied from this blog: https://medium.com/alphadev-thoughts/static-imports-are-great-but-underused-e805ba9b279f
So for example:
Assertions in tests
This is the most obvious case which I think we all agree on
Assertions.assertThat(1).isEqualTo(2);
// Use static import instead
assertThat(1).isEqualTo(2);
Utils classes and enums
The class name can be removed in many cases when using utils classes making the code easier to read
List<Integer> numbers = Arrays.asList(1, 2, 3);
// asList method name is enough information
List<Integer> numbers = asList(1, 2, 3);
java.time package has a few cases where it should be used
// Get next Friday from now, quite annoying to read
LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.FRIDAY));
// More concise and easier to read
LocalDate.now().with(next(FRIDAY));
Example of when NOT to use
// Ok this is an Optional
Optional.of("hello world");
// I have no idea what this is
of("hello world");
I agree that they can be problematic from a readability perspective and should be used sparingly. But when using a common static method they can actually increase readability. For example, in a JUnit test class, methods like assertEquals
are obvious where they come from. Similarly for methods from java.lang.Math
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With