Java:静态 - 非静态 - 这个问题

hhh*_*hhh 2 java static this non-static

$ 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
Run Code Online (Sandbox Code Playgroud)

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:定义"当前对象"

构造函数已创建,对象已创建,但未this引用当前对象 "test".当我将其更改为"test"但它不能与"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; }
}
Run Code Online (Sandbox Code Playgroud)

Eta*_*oin 12

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


Osc*_*Ryz 6

为什么我用"this"而不是"TestFilter"得到错误?

  • this用于表示"实例"属性或方法(以及其他).实例表示存在新对象,每个对象(实例)都具有给定属性的副本.

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

因此,在第一行中,您将声明filterFiles为类属性(您不需要实例).

看到:

private static final FileFilter filterFiles;
Run Code Online (Sandbox Code Playgroud)

这意味着,您声明了 名为:filterFiles of type的属性FileFilter,private并且其引用无法更改(因为它是final).

由于它是一个属性,您可以在main方法中访问它(这是一个类级方法).这两个都有效:

for(File f : file.listFiles(TestFilter.filterFiles)){
Run Code Online (Sandbox Code Playgroud)

for(File f : file.listFiles(filterFiles)){
Run Code Online (Sandbox Code Playgroud)

for(File f : file.listFiles(this.filterFiles)){
Run Code Online (Sandbox Code Playgroud)

不会,因为this引用当前实例,但由于你在类级方法(main)中没有实例,所以,没有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"

     }
}
Run Code Online (Sandbox Code Playgroud)

我希望这个样本能让一切清楚.