黑马程序员技术交流社区

标题: java对象实例化过程测试总结 [打印本页]

作者: jackwang    时间: 2015-3-22 01:06
标题: java对象实例化过程测试总结

class StaticCode
{
//        类的非静态成员变量(实例变量)定义语句:
//        作用:用来存储对象的特有数据的成员变量。
//        运行:当类对象被创建时就执行,按照顺序自上而下执行,和构造代码块平级。(即当有多个构造函数
//                代码块和多个非静态成员变量时,JVM按照自上而下的顺序来执行所有语句,包括构造代码块里的代码
//                和非静态成员的声明。)
//        存储位置:非静态变量位于堆内存中的对象实体中。
        int num = 3;
//        构造代码块
        {
                System.out.println("a        我是"构造代码块",当类对象被创建时,按照顺序执行");
        }
//        静态代码块。
//        作用:用来初始化类使用的。
//        运行:随着类的加载而执行,并且只执行一次,而且是自上向下执行的(即当有多个静态代码块,
//                和静态成员变量时,JVM自上向下执行每条语句。包括执行静态代码块里的代码,和根据静态成员的声明,
//                创建相应的变量)。
//        位置:其位于方法区(共享区、代码区)

//        注意:静态代码块和静态成员函数中只能使用静态成员,而不能使用非静态成员,原因是在使用(或执行)静态代码块
//        和静态成员函数时,非静态成员变量还没有被创建,因为只有在创建类对象时,非静态成员变量才在堆内存中被创建,
//        而之所以不能使用非静态成员函数,是因为非静态成员函数只能被类对象调用而不能被类名调用,所以,非静态成员中
//        是可以使用非静态成员变量的,所以如果静态代码块和静态成员函数若可以调用非静态成员函数,则会执行非静态成员
//        函数时,用到里面的非静态成员变量,而该非静态成员变量只有在创建类对象时才会被创建(才会存在)。所以就会导致
//        引用不存在的变量,出现错误。
        static int age =10;
        static
        {
                System.out.println("A:我是"静态代码块"!");
                System.out.println("A:age : "+age);
        }
//        构造代码块:
//        作用:用来初始化所有类对象的。
//        运行:在对象刚创建时就执行,优先于构造函数执行。
        String name = "张三" ;
        {
                System.out.println("B:我是"构造代码块"!");
                System.out.println("B:num : "+num);
                System.out.println("B:name : "+name);
        }
//        构造代码块
        {
                System.out.println("b        我是"构造代码块",当类对象被创建时,按照顺序执行");
        }
//        构造函数:
//        作用:用来初始化类的对象。
//        运行:当类对象被创建时运行。
        StaticCode()
        {
//                this.StaticCode(3);
                System.out.println("C        我是类的"构造函数"!");
        }
        StaticCode(int x)
        {
                System.out.println("构造函数之间的调用!");
        }
//        静态成员变量:又叫做类变量(区别于实例变量)
//        作用:用来存储被所有类对象所共享的数据
//        运行:随着类的加载就被创建了,直到类消失才会消失。生命周期最长。其可以直接用类名调用,即类名.静态成员变量名
//        存储:静态变量是位于方法区(共享区、代码区)
       
//        静态成员函数:
//        作用:不需要创建类对象就可以使用的功能(函数),即函数中没有使用类对象特有的数据,使用的都是
//                类对象共有的数据或其他数据。
//        运行:其可以直接用类名调用,即类名.静态成员函数名。也可以接受类对象调用,即类对象.静态成员函数
//        存储:其位于方法区(共享区、代码区)。
        public static void show()
        {
                System.out.println("我是"静态成员函数"");
        }
}

//        StaticCodeDemo 为主类,即含有主函数的类,并且是JVM首先加载的类(即 java 主类),所有含有主函数的类都是可以
//        独立运行的类。主类除了要被JVM首先调用和其中必须含有主函数之外,其他地方都与一个普通的java类没有任何区别就
//        也可以被创建对象,而主函数(即main函数)也不过是其的一个静态方法而已,只不过这个方法是会被JVM调用。所以也
//        可以有构造函数,也可以创建对象,并用对象去调用主函数,也可以将对象传递出去。
class StaticCodeDemo  
{
        static int cnt = 0;
        static
        {
                System.out.println("我是主类中的静态代码块,JVM首先需要将主类加载入内存中,从而引起我的执行,然后"+
                "才能调用主类中的方法(即主函数main方法),即 主类名.main(String[]型的变量)");
        }
        {
                System.out.println("--F--:构造代码块");
        }
        StaticCodeDemo()//构造函数的权限默认和类的权限一致,类是public,其就是public,类是private,其就是private。
        {
                System.out.println("--G--:构造函数");
        }
        public static void main(String[] args)
        {
//                JVM在运行主函数时,当首次使用到某类的时候,该类会被加载入内存,而编译的时候是不会将任何类加载进入内存的。
//                所以JVM会先将主类(主函数所在的类)加载入内存,然后再执行主函数,执行时若用到其他类的内容则会加载该类
//                进入内存,程序当中使用到类的内容的情况有两种,一种是,创建类对象(即 new 类名()),另一种是使用类名引用
//                静态成员(即 类名.静态成员)。
//                注意:创建类的引用(即 类名 类引用型变量名 = null),并不会使得类加载进入内存。因为创建引用并没有使用到
//                类定义中的任何信息。只是使用了类名,而类名会被解析成为一种自定义的类型名。任何类只有被加载入内存后,
//                才能使用里面的内容(包括创建类对象,因为创建类对象会使用到构造函数)。

//                new StaticCode();
//                System.out.println("--M--:主函数代码运行*******"+"cnt = "+cnt);
//                String[] arr= null;
//                if( cnt == 0 )
//                {
//                        cnt++;
//                        new StaticCodeDemo().main(arr); //main方法只不过是一个很普通的函数,很普通的类中的一个公共静态函数
////                                                                                          只不过为了和JVM协同工作(即配合JVM的调用),所以要写成固定的格式
////                                                                                          ,除此之外它完全符合一个类中的静态函数所具有的一切用法和特点。
////                                                                                                也完全可以被其他类的成员函数调用或自己调用自己(递归调用)。
//                }
//                else
//                {
//                        if( cnt == 1)
//                        {
//                                cnt++;
//                                main(arr);        //自己调用自己,递归调用
//                        }
//                }
                StaticCode.show();
        }
}







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2