对Eclipse中可变Java变量的警告

时间:2016-12-22 16:28:45

标签: java eclipse functional-programming

我对在Java中使用更多功能构造感兴趣,并且想知道如果我有可变的局部变量,参数,类成员等,是否有一种方法可以让它发出警告。这样,我我可以轻轻地迁移代码,因为我正在重构,并且在编写新代码时也会朝那个方向轻推。

我意识到FP并不是全部,但至少是一个开始。

感谢。

2 个答案:

答案 0 :(得分:0)

根据我的经验,无论您的IDE如何,您都可以使用final声明获得相当多的信息。

public class ImmutableThing {
  private final int someInt;
  private final String aString;
}

这里的想法是你在构造函数中设置一次,比方说,然后再也不要再碰它们了。 (你可以提供更清晰的setter方法,但是传达了这个对象是可变的不需要的概念。)Eclipse,IntelliJ等应该注意final声明并自然告诉你何时你有代码试图捣乱当它不应该与这些东西。 (我忘了他们是否会告诉你你是否宣布了最终的实例变量并且无法设置它。)

要注意的一个曲线球当然是对象,其字段可以在不改变ImmutableThing中字段值的情况下进行更改:

    private final List<String> strs; // Hmm.

您可以如上所述在构造函数中设置strs,但List的内容当然可以更改,所以这没有用。通常,您希望不可变的对象内的任何可变对象都会出现此问题。通过使用不可修改的集合,您可以在Collections(可能是最常见的可变对象)的情况下解决这个问题:

    strs = Collections.unmodifiableList<String>(initList);

或使用第三方版本,例如来自Guava:

    strs = ImmutableList<String>.of ("x", "y", "z");

其他对象可能提供不变性功能;他们可能不会。此功能可用性可能会影响您使用此范例的程度。一般来说,使用不可变数据对象可以获得相当远的距离,而且对于流和连接池等天生有状态的东西也不是很远。

答案 1 :(得分:0)

在Xmas度假期间疯狂发型,并决定使用解析器,以便能够获得可以从final中受益的地方列表。找到了javaparser.org,并将以下代码作为一个简单的开始运行,我希望继续前进:

import java.io.File;
import java.io.FileNotFoundException;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.commons.io.filefilter.RegexFileFilter;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.body.FieldDeclaration;

public class JavaFPMain {

    public static void main(String[] args) throws Exception {
        JavaFPMain fpApp = new JavaFPMain();
        fpApp.run();
    }

    private void run() throws Exception {
        File projectDir = new File(...);
        FileUtils.listFiles(projectDir, new RegexFileFilter(".*.java"), DirectoryFileFilter.DIRECTORY)
            .stream()
            .forEach(this::parseFile);

        System.out.println("done");
    }

    private void parseFile(final File fi) {
        try {
            CompilationUnit compilationUnit = JavaParser.parse(fi);

            String AUTOWIRED = "Autowired";
            compilationUnit.getNodesByType(FieldDeclaration.class).stream()
                .filter(f -> !f.getModifiers().contains(Modifier.FINAL) &&
                             !containsAnnotation(f, AUTOWIRED))
                .forEach(f -> System.out.println("missing final: " + fi.getAbsolutePath() + "(" + f.getBegin().get().line + ") " + f.getVariable(0).getNameAsString()));
        } catch (FileNotFoundException ex) {
            throw new RuntimeException(ex);
        }
    }

    private boolean containsAnnotation(FieldDeclaration f, String name) {
        return f.getAnnotations()
                .stream()
                .anyMatch(a -> a.getNameAsString().equals(name));
    }

}

是的,我从这里获得了6,000行输出,这意味着我的工作已经完成,我应该选择这样做。并且不包括应该制作final的参数,仍然可以修改的对象等。但同样,它还是一个可以开始的地方。