首先,非静态变量和方法是分开存储的,方法只有一个拷贝,为该类的所有实例共享。按照specification中的定义,静态方法是类的方法,非静态方法又叫做实例方法。比如:class A { public static void print() { System.out.println("static method."); } public void printString() { System.out.println("instance method."); } }你的代码中可以有A.print(),但不能有A.printString(),否则编译报错。创建一个实例之后A a = new A();既可以使用a.printString(),也可以使用a.print()。虽然sun不提倡a.print(),但可以执行,并且大多情况下(极少数情况我没碰到过)正常执行。这说明从实例的角度看,二者是一致的。静态变量可以保证在所有实例对象共享一份拷贝,静态方法的意义是什么?为了在面向对象的体系中获得全局方法的折衷方案?
使用Reflex,从ClassLoader角度可能对理解这个问题有帮助。import java.lang.annotation.*; import java.lang.reflect.*;public class TestClassObject { public static void main(String[] args) throws Exception{ ClassA a = new ClassA(); ClassB b = new ClassB(); Class classA = Class.forName("ClassA"); Object instanceOfClassA = classA.newInstance(); // follows is invocation of the static method of ClassA. Method printObject = classA.getMethod("print", Object.class); System.out.println("reflex method: " + printObject); System.out.println("-------------------------------------------"); // equivalent to ClassA.print(Object) printObject.invoke(classA, classA); // equivalent to "a Instance Of ClassA".print(Object) printObject.invoke(instanceOfClassA, instanceOfClassA); // equivalent to a.print(Object) printObject.invoke(a, a); System.out.println(); // follows is invocation of the non-static method of ClassA. Method printInt = classA.getMethod("print", int.class); System.out.println("reflex method: " + printInt); System.out.println("-------------------------------------------"); // equivalent to instanceOfClass.print(1) printInt.invoke(instanceOfClassA, 1); // equivalent to a.print(1) printInt.invoke(a, 2); try { printInt.invoke(classA, 3); } catch (Exception e) { System.out.println("\nInstance method can't be invoked by its Class."); } try { printInt.invoke(b, 2); } catch (Exception e) { System.out.println("\nMethod belongs to a Class can't be invoked " + "by instance of another class, although the two Class looks like the same.\n"); } } }class ClassA { public static void print(Object o){ System.out.println("static method invoked by " + o); }; public void print(int i) { System.out.println("parameter's value is: " + i); } }// ClassB is a full copy from ClassA, just with difference name. class ClassB { public static void print(Object o){ System.out.println("static method invoked by " + o); }; public void print(int i) { System.out.println("parameter's value is: " + i); } }---------- 运行结果 ---------- reflex method: public static void ClassA.print(java.lang.Object) ------------------------------------------- static method invoked by class ClassA //class static method invoked by ClassA@d9f9c3 //instance static method invoked by ClassA@9cab16 //another instancereflex method: public void ClassA.print(int) ------------------------------------------- parameter's value is: 1 parameter's value is: 2Instance method can't be invoked by its Class.Method belongs to a Class can't be invoked by instance of another class, although the two Class looks like the same.
public static void print() {
System.out.println("static method.");
}
public void printString() {
System.out.println("instance method.");
}
}你的代码中可以有A.print(),但不能有A.printString(),否则编译报错。创建一个实例之后A a = new A();既可以使用a.printString(),也可以使用a.print()。虽然sun不提倡a.print(),但可以执行,并且大多情况下(极少数情况我没碰到过)正常执行。这说明从实例的角度看,二者是一致的。静态变量可以保证在所有实例对象共享一份拷贝,静态方法的意义是什么?为了在面向对象的体系中获得全局方法的折衷方案?
import java.lang.reflect.*;public class TestClassObject {
public static void main(String[] args) throws Exception{
ClassA a = new ClassA();
ClassB b = new ClassB(); Class classA = Class.forName("ClassA");
Object instanceOfClassA = classA.newInstance();
// follows is invocation of the static method of ClassA. Method printObject =
classA.getMethod("print", Object.class);
System.out.println("reflex method: " + printObject);
System.out.println("-------------------------------------------"); // equivalent to ClassA.print(Object)
printObject.invoke(classA, classA); // equivalent to "a Instance Of ClassA".print(Object)
printObject.invoke(instanceOfClassA, instanceOfClassA); // equivalent to a.print(Object)
printObject.invoke(a, a); System.out.println();
// follows is invocation of the non-static method of ClassA. Method printInt =
classA.getMethod("print", int.class);
System.out.println("reflex method: " + printInt);
System.out.println("-------------------------------------------"); // equivalent to instanceOfClass.print(1)
printInt.invoke(instanceOfClassA, 1);
// equivalent to a.print(1)
printInt.invoke(a, 2); try {
printInt.invoke(classA, 3);
} catch (Exception e) {
System.out.println("\nInstance method can't be invoked by its Class.");
} try {
printInt.invoke(b, 2);
} catch (Exception e) {
System.out.println("\nMethod belongs to a Class can't be invoked " +
"by instance of another class, although the two Class looks like the same.\n");
}
}
}class ClassA {
public static void print(Object o){
System.out.println("static method invoked by " + o);
}; public void print(int i) {
System.out.println("parameter's value is: " + i);
}
}// ClassB is a full copy from ClassA, just with difference name.
class ClassB {
public static void print(Object o){
System.out.println("static method invoked by " + o);
}; public void print(int i) {
System.out.println("parameter's value is: " + i);
}
}---------- 运行结果 ----------
reflex method: public static void ClassA.print(java.lang.Object)
-------------------------------------------
static method invoked by class ClassA //class
static method invoked by ClassA@d9f9c3 //instance
static method invoked by ClassA@9cab16 //another instancereflex method: public void ClassA.print(int)
-------------------------------------------
parameter's value is: 1
parameter's value is: 2Instance method can't be invoked by its Class.Method belongs to a Class can't be invoked by instance of another class, although the two Class looks like the same.