java cannot make a static reference to the non-static method
我最後,還是無法理解和運用static, 這似乎太難.
I am not able to understand what is wrong with my code.
class Two {
public static void main(String[] args) {
int x = 0;
System.out.println("x = " + x);
x = fxn(x);
System.out.println("x = " + x);
}
int fxn(int y) {
y = 5;
return y;
}
}
Exception in thread “main” java.lang.Error: Unresolved compilation problem: Cannot make a static reference to the non-static method fxn(int) from the type Two
Since the main
method is static
and the fxn()
method is not, you can’t call the method without first creating a Two
public static int fxn(int y) {
y = 5;
return y;
}
or change the code in main
to:
Two two = new Two();
x = two.fxn(x);
Read more on static
here in the Java Tutorials.
static這關鍵字能使用在inner class/method/variable,什麼時候會需要static的variable?
當該變數屬於某一class時,而不是屬於某一instance時,就會使用static variable。無論在任何instance中,存取的static variable都是相同的,或是說該static variable在memory中只有一份,存取時都是取該memory的資料。
當定一method為static時,代表該method屬於class,就是說不需要instance就能使用該method,當然就沒有new的動作,大部分的utility methods都是定為static的。如果在static method使用non-static variable時,會發生compile error。static method在instance尚未建立前就能使用(call),那non-static variable都沒生成,這樣static method要怎麼用?
下面的程式會發生錯誤,錯誤訊息為”Cannot make a static reference to the non-static field var”。
1 2 3 4 5 6 7 8 9 |
public class InvokeNonStaticVariable {
private int var = 1 ;
public static void main(String[] args) {
System.out.println(var);
}
}
|
static variable在class loading時就建立,而instance variable(InvokeNonStaticVariable中的var)在new的時候才會建立。
static method是無法覆寫的,因為它是屬於class的,從下面的程式碼來說明。定義時就是定義為class A,即使用new B( ),但前面提到static member是屬於class的,與生成的instance無關。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class A {
public static void printName() {
System.out.println( "A" );
}
public void printNumb() {
System.out.println( "65" );
}
}
public class B extends A {
public static void printName() {
System.out.println( "B" );
}
public void printNumb() {
System.out.println( "66" );
}
}
public class StaticMethodOverrideExample {
public static void main(String[] args) {
A a = new B();
B b = new B();
a.printName();
a.printNumb();
b.printName();
b.printNumb();
}
}
|
執行後的結果為
1 2 3 4 |
A
66
B
66
|
static method不能override的部份是指在printName中,a.printName()輸出的依然是A,但是在a.printNumb()輸出的卻是class B中設定的66。另外如果是eclipse,會建議使用者將程式修改為直接call static method,如下。
1 2 3 4 5 6 7 8 9 10 11 |
public class FixStaticMethodOverrideExample {
public static void main(String[] args) {
A a = new B();
B b = new B();
A.printName();
a.printNumb();
B.printName();
b.printNumb();
}
}
|
我在一個類中寫了一個public void getDate()方法和一個main方法,在main方法中直接呼叫getDate()方法,於是就出現了這個錯誤提示。後來例項化類,再用例項化的類呼叫getDate()方法就沒問題了。
在靜態方法中,不能直接訪問非靜態成員(包括方法和變數)。
因為,非靜態的變數是依賴於物件存在的,物件必須例項化之後,它的變數才會在記憶體中存在。例如一個類 Student 表示學生,它有一個變數 String address。如果這個類沒有被例項化,則它的 address 變數也就不存在。而非靜態方法需要訪問非靜態變數,所以對非靜態方法的訪問也是針對某一個具體的物件的方法進行的。對它的訪問一般通過 objectName.methodName(args……) 的方式進行。
而靜態成員不依賴於物件存在,即使是類所屬的物件不存在,也可以被訪問,它對整個程序而言是全域性的。因此,在靜態方法內部是不可以直接訪問非靜態成員的。
Static methods cannot call non-static methods. An instance of the class is required to call its methods and static methods are not accociated with an instance (they are class methods). To fix it you have a few choices depending on your exact needs.
/** * Will not compile */ public class StaticReferenceToNonStatic { public static void myMethod() { // Cannot make a static reference // to the non-static method myNonStaticMethod(); } public void myNonStaticMethod() { } } /** * you can make your method non-static */ public class MyClass { public void myMethod() { myNonStaticMethod(); } public void myNonStaticMethod() { } } /** * you can provide an instance of the * class to your static method for it * to access methods from */ public class MyClass { public static void myStaticMethod(MyClass o) { o.myNonStaticMethod(); } public void myNonStaticMethod() { } } /** * you can make the method static */ public class MyClass { public static void myMethod() { f(); } public static void f() { } }
報錯原因:
在一個類中寫了一個public String getContent()方法和一個main()方法,getContent()方法中包含了getClass()方法,在main()方法中直接呼叫了getContent()就出現如題的錯誤。這樣一樣
解決方法:
先例項化類,然後再呼叫getContent()就沒有問題了
- GetProperties gp = new GetProperties();
- String s = gp.getCotent();
說明:
在靜態方法中,不能直接訪問非靜態成員(包括方法和變數)。因為,非靜態的變數是依賴於物件存在的,物件必須例項化之後,它的變數才會在記憶體中存在。例如一個類 Student 表示學生,它有一個變數String address。如果這個類沒有被例項化,則它的 address 變數也就不存在。而非靜態方法需要訪問非靜態變數,所以對非靜態方法的訪問也是針對某一個具體的物件的方法進行的。對它的訪問一般通過 objectName.methodName(args……) 的方式進行。而靜態成員不依賴於物件存在,即使是類所屬的物件不存在,也可以被訪問,它對整個程序而言是全域性的。因此,在靜態方法內部是不可以直接訪問非靜態成員的。
Source Code如下:
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.io.InputStream;
- import java.util.Properties;
- public class GetProperties {//不用static
- public String getCotent(){//不用static
- String content=””;
- try {
- Properties properties = new Properties();
- InputStream is = getClass().getResourceAsStream(“test.properties”);//ok
- //InputStream is = getClass().getClassLoader().getResourceAsStream(“test.properties”); //ERROR:Exception in thread “main” java.lang.NullPointerException
- properties.load(is);
- is.close();
- content = properties.getProperty(“str1″);
- } catch (FileNotFoundException ex) {
- ex.printStackTrace();
- }catch (IOException ex) {
- ex.printStackTrace();
- }
- return content;
- }
- public static void main(String[] args){
- GetProperties gp = new GetProperties();//例項化
- String s = gp.getCotent();
- System.out.println(s);
- }
- }
- test.properties中內容為str1=123