在对象存储中,静态变量是属于类所有,非静态变量在每个对象中都分配有存储空间,那么类中的方法是如何存储的?是一个类只有一个方法列表,还是每个对象中都有方法列表??此时,对于静态方法和非静态方法存储有区别吗?

解决方案 »

  1.   

    首先,非静态变量和方法是分开存储的,方法只有一个拷贝,为该类的所有实例共享。按照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(),但可以执行,并且大多情况下(极少数情况我没碰到过)正常执行。这说明从实例的角度看,二者是一致的。静态变量可以保证在所有实例对象共享一份拷贝,静态方法的意义是什么?为了在面向对象的体系中获得全局方法的折衷方案?
      

  2.   

    使用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.