2010-04-12 41 views
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 '[email protected]@[email protected]' TestFilter.java 
$ javac TestFilter.java 
$ java TestFilter 
file1 
file2 
file3 

TestFilter.java的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; } 
} 
+1

引用'Update:define'当前对象'':“this”只存在于“内部”实例(非静态)方法中。在实例方法之外,您必须通过外部变量“test”引用实例。 – 2010-04-12 20:47:22

回答

6

为什么我得到“this”错误,但没有“TestFilter”?

  • this被用来指 “实例” 属性或方法(除了别的以外)。实例表示存在一个新对象,每个对象(实例)都有一个给定属性的副本。

  • class name(你的情况TestFilter)被用来指“类”的属性或方法(那些谁不需要一个实例extist。

所以,在你的第一行,你”再次声明filterFiles作为类属性(您不需要为实例

参见:

private static final FileFilter filterFiles; 

这意味着,您声明类别属性名称:filterFiles类型FileFilter这是private并且其参考不能更改(因为它是final)。

由于它是类别属性,您可以在main方法(这是一个类级别的方法)中访问它。这既会工作:

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

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

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

,因为this指当前实例,但因为你在一个类级别的方法是(主)没有实例,所以没有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" 

    } 
} 

我希望这样品让一切都清楚了。

+0

感谢您的示例。希望源代码可用,并对API感到沮丧。 – hhh 2010-04-12 21:32:25

12

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

+0

请定义术语“当前对象”。我试图用“this”引用当前对象“测试”,但它不起作用:http://stackoverflow.com/questions/2625031/java-static-non-static-this-problem/2625219#2625219 – hhh 2010-04-12 20:31:40

+0

澄清“这指的是当前对象”:当你调用一个实例方法(非静态方法)时,有一个叫做“this”的“隐含变量”,它指向你调用该方法的实例。当你调用静态方法时,这个“隐含变量”(“this”)不存在,看起来合乎逻辑的是,当你调用一个静态方法时,“当前对象”/“this”是类,但它这个方法不起作用。静态方法没有“this”。 – 2010-04-12 20:44:00

+0

定义:当前对象是一个非静态方法,你可以实例化,使用“this”INSIDE - – hhh 2010-04-12 21:05:30

0

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

如果TestFilter是应该实例化为类的东西,我建议将主函数内的代码移到构造函数中。在这种情况下,你将能够访问“this”。

0

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

0

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

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