Java: static-non-static-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);
}
}
}
Update: define "current object"
Constructor created, object created but the this
does not refer to the current object "test". It works when I change this to "test" but it does not 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; }
}
The keyword this
refers to the current object -- something that you don't have, because your method is static. That means it's running on the class itself, not on any object, so any use of this
is invalid -- even though the specific variable you're trying to access is static too. The correct way to access a static member is by the class: TestFilter.filterFiles
, not this.filterFiles
.
Why do I get the error with "this" but not with "TestFilter"?
this
is used to refer to "instance" attributes or method ( among others ). Instance means a new object exist and each object ( instance ) have a copy of the given attribute.The
class name
( in your caseTestFilter
) is used to refer to "class" attributes or methods ( those who do not require an instance to extist.
So, in your first line you're declaring filterFiles
as a class attribute ( you don't require an instance for that.
See:
private static final FileFilter filterFiles;
This means, you declare class attribute named: filterFiles
of type FileFilter
which is private
and whose reference can't be changed ( because it is final
).
Since it is a class attribute you may access it in the main
method ( which is a class level method ). This both will work:
for(File f : file.listFiles(TestFilter.filterFiles)){
and
for(File f : file.listFiles(filterFiles)){
But
for(File f : file.listFiles(this.filterFiles)){
Won't, because this
refers to the current instance, but since you're in a class level method ( main ) there is no instance, so, there is no this
or in compiler words: non-static variable this cannot be referenced from a static context
Instance attributes are unique per instance. Class level attribute are unique per 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"
}
}
I hope this sample make everything clear.
you cannot reference instance variables like the "this" pointer in static functions. Since TestFilter is the class and the filterFiles variable is static, it works, because you can use static vars in static functions.
If TestFilter is something that is supposed to be instantiated as a class, I suggest moving the code inside the main function to the constructor. In that case, you would be able to access "this".
this is a reference to the instance of the object actually used. In a static method the class wasn't instantiated - this has no meaning in this context.
Static members are referenced by Class, not by instance. What this means is that you must use class name to reference the static member, not instance name.
Because this
refers to an instance, you get compile error.
精彩评论