2
$ 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

测试过滤器.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);
        }
    }
}

更新:定义“当前对象”

构造函数已创建,对象已创建但this不引用当前对象“测试”。当我将其更改为“测试”时它可以工作,但它不适用于“这个”。为什么?

$ 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; }
}
4

5 回答 5

12

关键字this指的是当前对象——你没有的东西,因为你的方法是静态的。这意味着它在类本身上运行,而不是在任何对象上运行,因此任何使用this都是无效的——即使您尝试访问的特定变量也是静态的。访问静态成员的正确方法是通过类:TestFilter.filterFiles,而不是this.filterFiles

于 2010-04-12T20:08:33.627 回答
6

为什么我会收到“this”的错误,而不是“TestFilter”?

  • this用于指代“实例”属性或方法(除其他外)。实例意味着存在一个新对象,并且每个对象(实例)都具有给定属性的副本。

  • class name在您的情况下TestFilter)用于指代“类”属性或方法(那些不需要实例即可存在的属性或方法。

因此,在您的第一行中,您将声明filterFiles为类属性(您不需要为此提供实例。

看:

private static final FileFilter filterFiles;

这意味着,您声明了 名为:的filterFiles属性,其 类型FileFilterprivate并且其引用不能更改(因为它是final)。

由于它是一个属性,您可以在main方法中访问它(这是一个类级别的方法)。这两者都将起作用:

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

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

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

不会,因为this指的是当前实例,但是由于您在类级别方法( main )中没有实例,所以this编译器中没有 or :非静态变量 this 不能从静态引用语境

每个实例的实例属性都是唯一的。每个类的类级别属性是唯一的。

考虑以下类:

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"

     }
}

我希望这个样本能让一切变得清晰。

于 2010-04-12T20:31:37.017 回答
0

您不能在静态函数中引用实例变量,例如“this”指针。由于 TestFilter 是类并且 filterFiles 变量是静态的,因此它可以工作,因为您可以在静态函数中使用静态变量。

如果 TestFilter 应该被实例化为一个类,我建议将 main 函数中的代码移动到构造函数中。在这种情况下,您将能够访问“this”。

于 2010-04-12T20:09:05.500 回答
0

这是对实际使用的对象实例的引用。在静态方法中,该类没有被实例化——这在这种情况下没有意义。

于 2010-04-12T20:11:36.170 回答
0

静态成员由类引用,而不是由实例引用。这意味着您必须使用类名来引用静态成员,而不是实例名。

因为this引用了一个实例,所以会出现编译错误。

于 2010-04-12T20:47:27.343 回答