2010-04-12 47 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引用了一個實例,所以會出現編譯錯誤。