动手动脑-3

package 动手动脑;

public class 试验 {
public static void main(String[] args) {
    Foo  obj1=new Foo();
    Foo  obj2=new Foo();
    System.out.println(obj1==obj2);
}
}
class  Foo{
    int value=100;
}

这个程序的运行结果是false,建立类Foo的对象obj1,然后立刻又建了类Foo的对象obj2,这两个对象是不同的,就像是克隆了一个新的对象,所以最终结果为false.

构造方法的特殊之处:1、没有返回值

                                   2、与类名相同

                                   3、对对象进行初始化

                                   4、在建类时自动建立一个默认构造函数,但是如果自己建立了有参构造函数,将不再自动建立默认构造函数。

package 动手动脑;

public class InitializeBlockClass {
    {
        field=200;
    }
    public int field=100;
    public InitializeBlockClass(int value) {
        this.field=value;
    }
    public InitializeBlockClass() {
        
    }
    public static void main(String[]args) {
        InitializeBlockClass obj=new InitializeBlockClass();
        System.out.println(obj.field);
        obj=new InitializeBlockClass(300);
        System.out.println(obj.field);
    }
}

这个程序的运行结果是:100

                                       300

第一次建立对象调用的是无参构造函数,然后就要调用上面的field的值,这是采用就近原则,所以第一次输出field的值为100,第二次建立对象,调用的是有参构造函数,这是构造函数自己赋值为300,所以第二次输出为300.

 Java字段初始化的规律:

静态初始化生成实例变成你赋给他的值,先执行静态初始化,如果没有实例化,按照初始化和构造方法在程序中出现的顺序执行。

当多个类之间有继承关系时,创建子类对象会导致父类初始化块的执行。

class Root
{
    static{
        System.out.println("Root的静态初始化块");
    }
    {
        System.out.println("Root的普通初始化块");
    }
    public Root()
    {
        System.out.println("Root的无参数的构造器");
    }
}
class Mid extends Root
{
    static{
        System.out.println("Mid的静态初始化块");
    }
    {
        System.out.println("Mid的普通初始化块");
    }
    public Mid()
    {
        System.out.println("Mid的无参数的构造器");
    }
    public Mid(String msg)
    {
        //通过this调用同一类中重载的构造器
        this();
        System.out.println("Mid的带参数构造器,其参数值:" + msg);
    }
}
class Leaf extends Mid
{
    static{
        System.out.println("Leaf的静态初始化块");
    }
    {
        System.out.println("Leaf的普通初始化块");
    }    
    public Leaf()
    {
        //通过super调用父类中有一个字符串参数的构造器
        super("Java初始化顺序演示");
        System.out.println("执行Leaf的构造器");
    }

}

public class TestStaticInitializeBlock
{
    public static void main(String[] args) 
    {
        new Leaf();
        

    }
}

运行结果为:

Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:Java初始化顺序演示
Leaf的普通初始化块
执行Leaf的构造器

 通过运行结果我发现:在调用这个方法时,有super,调用父类,然后先调用第一个父类中的静态初始化块,然后调用子类的静态初始化块,然后调用子类的子类中的静态初始化块,接着调用父类中的普通初始化块和无参的构造块,然后子类中的普通、无参构造、有参构造初始化块,最后调用方法中System.out.println()中要输出的内容
静态初始化块的执行顺序为:
  1. 静态初始化块的优先级最高,也就是最先执行,并且仅在类第一次被加载时执行;
  2. 非静态初始化块和构造函数后执行,并且在每次生成对象时执行一次;
  3. 非静态初始化块的代码会在类构造函数之前执行。因此若要使用,应当养成把初始化块写在构造函数之前的习惯,便于调试;
  4. 静态初始化块既可以用于初始化静态成员变量,也可以执行初始化代码;
  5. 非静态初始化块可以针对多个重载构造函数进行代码复用。
    package 动手动脑;
    
    public class 静态方法 {
    public static int a=10;
    public void  setvalue() {
        System.out.println(a);
    }
    public static void main(String[]args) {
        System.out.println(a);
        静态方法 j=new 静态方法();
        j.setvalue();
    }
    }

    程序的运行结果为:10  10  说明静态方法可以调用静态变量,非静态方法也可以调用静态变量。

猜你喜欢

转载自www.cnblogs.com/zhaoxinhui/p/9825773.html