What is a good use case for static import of metho

2019-01-02 22:24发布

Just got a review comment that my static import of the method was not a good idea. The static import was of a method from a DA class, which has mostly static methods. So in middle of the business logic I had a da activity that apparently seemed to belong to the current class:

import static some.package.DA.*;
class BusinessObject {
  void someMethod() {
    ....
    save(this);
  }
} 

The reviewer was not keen that I change the code and I didn't but I do kind of agree with him. One reason given for not static-importing was it was confusing where the method was defined, it wasn't in the current class and not in any superclass so it too some time to identify its definition (the web based review system does not have clickable links like IDE :-) I don't really think this matters, static-imports are still quite new and soon we will all get used to locating them.

But the other reason, the one I agree with, is that an unqualified method call seems to belong to current object and should not jump contexts. But if it really did belong, it would make sense to extend that super class.

So, when does it make sense to static import methods? When have you done it? Did/do you like the way the unqualified calls look?

EDIT: The popular opinion seems to be that static-import methods if nobody is going to confuse them as methods of the current class. For example methods from java.lang.Math and java.awt.Color. But if abs and getAlpha are not ambiguous I don't see why readEmployee is. As in lot of programming choices, I think this too is a personal preference thing.

Thanks for your response guys, I am closing the question.

16条回答
时光不老,我们不散
2楼-- · 2019-01-02 23:03

I found this to be very convenient when using Utility classes.

For example , instead of using : if(CollectionUtils.isNotEmpty(col))

I can instead :

import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
if(isNotEmpty(col))

Which IMO increases code readability when I use this utility multiple times in my code.

查看更多
相关推荐>>
3楼-- · 2019-01-02 23:06

I use it for Color a lot.

static import java.awt.Color.*;

It is very unlikely that the colors will be confused with something else.

查看更多
叼着烟拽天下
4楼-- · 2019-01-02 23:08

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.

查看更多
做自己的国王
5楼-- · 2019-01-02 23:08

I recommend the use of static import when using OpenGL with Java, which is a use-case falling into the "heavy use of constants from a utility class" category

Consider that

import static android.opengl.GLES20.*;

allows you to port original C code and write something readable such as :

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(samplerUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, vtxBuffer);
glVertexAttribPointer(vtxAttrib, 3, GL_FLOAT, false, 0, 0);

instead of that common widespread ugliness :

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glUniform1i(samplerUniform, 0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vtxBuffer);
GLES20.glVertexAttribPointer(vtxAttrib, 3, GLES20.GL_FLOAT, false, 0, 0);
查看更多
三岁会撩人
6楼-- · 2019-01-02 23:10

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.

查看更多
女痞
7楼-- · 2019-01-02 23:10

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");
查看更多
登录 后发表回答