0

If I have the following code to walk through a directory and want to find a specific file.

The following works:

List<Path> foundPaths = new ArrayList<Path>();
PathMatcher pathMatcher = "regex:.*somefile.exe";
Path downloadLocation = Paths.get("C:\Downloads");

try {
  Files.walkFileTree(downloadLocation, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      if (pathMatcher.matches(file)) {
        foundPaths.add(file);
      }

      return FileVisitResult.CONTINUE;
    }
  });
} catch (Exception e) {}

But if I want to store only a single file variable instead of adding it to a list, it fails to compile.

The following code generates the message "Local variable filePath defined in an enclosing scope must be final or effectively final"

Path filePath = null;
PathMatcher pathMatcher = "regex:.*somefile.exe";
Path downloadLocation = Paths.get("C:\Downloads");

try {
  Files.walkFileTree(downloadLocation, new SimpleFileVisitor<Path>() {
    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
      if (pathMatcher.matches(file)) {
        filePath = file;
      }

      return FileVisitResult.CONTINUE;
    }
  });
} catch (Exception e) {}

What am I missing as to why the reference can't be copied to filePath? Is there a solution to store just the single file Path?

dranobob
  • 796
  • 1
  • 5
  • 19
  • 1
    Possible duplicate of [Problems with local variable scope. How to solve it?](https://stackoverflow.com/questions/25894509/problems-with-local-variable-scope-how-to-solve-it) – J-Alex Jul 24 '17 at 21:08
  • I read this post, but can't seem to see how this allows me to assign to the outer variable, what am I missing? – dranobob Jul 24 '17 at 21:11
  • @dranobob You didn't read it: "*you are trying to access a local variable from within an anonymous inner class and the scope is not enough. So it definitely must be `final`*". What you are trying to do won't work, since local variables must be final to be accessed within an anonymous class. – Vince Jul 24 '17 at 21:15
  • More specifically, my main question is why we can do the add for a list but direct variable assignment doesn't work. the possible duplicate post above doesn't seem to address this question. – dranobob Jul 24 '17 at 21:15
  • @Vince I did read it, but I don't know what needs to be set as final? – dranobob Jul 24 '17 at 21:16
  • @dranobob The local variable. `List` can be accessed because it's *[effectively final](https://stackoverflow.com/questions/20938095/difference-between-final-and-effectively-final)*. Your error tells you everything. – Vince Jul 24 '17 at 21:18
  • ah, ok I think I understand, because the list reference never changes. – dranobob Jul 24 '17 at 21:19
  • As I understood from you code, using a `final` in your case will not work as you planned (the main logic is to change reference). You can use `filePath` as instance variable, not as a local variable. – J-Alex Jul 24 '17 at 21:23
  • Use array `Path[] filePath = {null};` and store `filePath[0] = file;`. –  Jul 24 '17 at 21:26
  • I appreciate all the help. I guess I'll just use the array list for now (or create a small class for just getting the path). I apparently did not understand the "effectively final" message, but it all makes sense now as to why Lists works. – dranobob Jul 24 '17 at 21:29

0 Answers0