Java: static-non-static is this problem

$ javac TestFilter.java 
TestFilter.java:19: non-static variable this cannot be referenced from a static context
        for(File f : file.listFiles(this.filterFiles)){
                                    ^
1 error
$ sed -i 's@this@TestFilter@g' TestFilter.java 
$ javac TestFilter.java 
$ java TestFilter
file1
file2
file3

      

TestFilter.java

import java.io.*;
import java.util.*;

public class TestFilter {
    private static final FileFilter filterFiles;

    // STATIC!
    static{
        filterFiles = new FileFilter() {
            // Not Static below. When static, an error:
            // "accept(java.io.File) in  cannot implement 
            // accept(java.io.File) in java.io.FileFilter; 
            // overriding method is static"
            //
            // I tried to solve by the change the problem at the bottom.

            public boolean accept(File file) {
                return file.isFile();
            }
        };
    }

   // STATIC!
    public static void main(String[] args){
        HashSet<File> files = new HashSet<File>();
        File file = new File(".");

            // IT DID NOT WORK WITH "This" but with "TestFilter".
            // Why do I get the error with "This" but not with "TestFilter"?

        for(File f : file.listFiles(TestFilter.filterFiles)){
            System.out.println(f.getName());
            files.add(f);
        }
    }
}

      

Refresh: define "current object"

A constructor created, an object created, but this

not related to the current "test" object. It works when I change it to "test", but it doesn't work with "this". Why?

$ javac TestFilter.java 
TestFilter.java:28: non-static variable this cannot be referenced from a static context
        for(File f : this.getFiles()){
                     ^
1 error
$ cat TestFilter.java 
import java.io.*;
import java.util.*;

public class TestFilter {

    private static final FileFilter filterFiles;
    private HashSet<File> files;

    static{
        filterFiles = new FileFilter() {
            public boolean accept(File file) {
                return file.isFile();
            }
        };
    }

    TestFilter(){
        files = new HashSet<File>();
        File file = new File(".");

        for(File f : file.listFiles(filterFiles)){
            files.add(f);
        }
    }

    public static void main(String[] args){

        // CONSTRUCTOR with no pars invoked and object "test" created here!

        TestFilter test = new TestFilter();

        // Why does it not work with "this"? 
        // "test" is surely the current object.

        for(File f : this.getFiles()){
            System.out.println(f.getName());    
        }
    }

    public HashSet<File> getFiles() { return files; }
}

      

+2


source to share


5 answers


Why am I getting an error with "this" but not with "TestFilter"?

  • this

    used to refer to attributes or methods of an instance (among others). Instance means that a new object exists and each object (instance) has a copy of the given attribute.

  • class name

    (in your case TestFilter

    ) is used to refer to attributes or methods of a class (those that don't require an instance to be exposed.

So, in your first line, you are declaring filterFiles

as a class attribute (you don't need an instance for that.

Cm:

private static final FileFilter filterFiles;

      

This means that you are declaring a class attribute with a name: of filterFiles

type FileFilter

, which is private

and the reference to which cannot be changed (as it is final

).

Since it is a class attribute , you can access it in a method main

(which is a class level method). This will work:

for(File f : file.listFiles(TestFilter.filterFiles)){

      

and



for(File f : file.listFiles(filterFiles)){

      

But

for(File f : file.listFiles(this.filterFiles)){

      

It won't because it this

refers to the current instance, but since you are in a class-level method (main) there is no instance, so there is no this

or in the words of the compiler: a static variable that cannot be referenced from a static context

Instance attributes are unique to each instance. The class level attribute is unique for each class.

Consider the following class:

import static java.lang.System.out;
class Employee  {
     // class level counter. It exist regardless of the instances created.
     public static int employeeCount = 0;
     // instance attribute. Each one is different from others instances
     private String employeeName;

     // Class level method, can be invoked without instance.
     public static Employee createEmployee( String withName ) {

         Employee e = new Employee();
         // Set the name to the instance
         e.employeeName = withName;
         // Increments the class counter
         Employee.employeeCount++;
         return e;
     }
     // Object constructor.
     public Employee() {
          out.println("Constructor invoked!!! A new object has born, yeah!");
     }
     // Instance method "toString()"
     public String toString() {
         // Uses "this" to refer instance level method
         return this.emploeeName;
     }

     // Test
     public static void main( String [] args ) {

          // The counter already exist
          out.printf("Employees created %d%n", Employee.employeeCount );
          // Create employee a
          Employee a = Employee.createEmployee("Oscar");
          // Its name now exists 
          out.printf("Employee name: %s %nEmployees created %d%n",
                      a.employeeName,  Employee.employeeCount );
          // Create employee b with a new name 
          Employee b = Employee.createEmployee("HH");
          out.printf("Employee name: %s %nEmployees created %d%n", 
                      b.employeeName,  Employee.employeeCount );
          // Now both employees exist, each one with a name 
          out.printf("a=%s, b=%s%n, a, b );// invoke toString method which in turn uses "this"

     }
}

      

Hope this pattern makes it clear.

+6


source


The keyword this

refers to the current object - something you don't have because your method is static. This means that it works on the class itself and not on any object, so any use this

is invalid, even if the particular variable you are trying to access is also static. The correct way to access a static member belongs to the: class TestFilter.filterFiles

, not this.filterFiles

.



+12


source


you cannot reference instance variables such as the "this" pointer in static functions. Since TestFilter is a class and filterFiles variable is static, it works because you can use static vars in static functions.

If TestFilter is what you intend to create as a class, then I suggest moving the code inside the main function to the constructor. In this case, you will be able to access "this".

0


source


it is a reference to an instance of the object being used. In a static method, the class was not instantiated - that doesn't make sense in this context.

0


source


Static members refer to a class, not an instance. This means that you must use the class name to refer to the static member, not the instance name.

Since it this

refers to an instance, you get a compilation error.

0


source







All Articles