笔记9

来源:互联网 发布:西安新城网络花店 编辑:程序博客网 时间:2024/05/17 03:36

在了解this之后能更好的理解用static修饰的方法。static方法:没有this的方法。具体可以想到java内部如同python的方法调用结构:方法第一个参数为该类的对象(this),而static方法没有这个this对象,所以说this压根没传到static方法里,所以在static方法中不能调用非静态的方法(因为没有this嘛,非静态的方法需要this才行运转)。但是反过来,在非静态的方法中可以调用静态方法。
静态方法可以在不创建该类对象的情况下,用类名.方法名()直接使用。

public class H{       boolean bool;    char c;    byte b;    short s;    int i;    long l;    float f;    double d;    String str;    H haha;    void printf()    {        print("boolean "+bool);        print("char "+c);        print("byte "+b);        print("short "+s);        print("int "+i);        print("long "+l);        print("float "+f);        print("double "+d);        print("String "+str);        print("H "+haha);    }    public static void main(String[] args)    {        H ob=new H();        ob.printf();    }                  

输出:
这里写图片描述

package net.mindview;import static net.mindview.util.Print.*;//1:给类中变量初始化的一种方式是直接赋值。//2:也可以用函数给变量赋值//3:给变量赋值的顺序是自上而下的,因此不能在一个变量的赋值方法中使用当前还没赋值的变量(该变量下方的变量)class A{}public class H{   //直接赋值    boolean bool=true;    char c='a';    byte b=1;    short s=2;    int i=3;    long l=4;    float f=1.1f;    double d=2.2;    String str="hello world";    A haha=new A();    //int w=g(v);//报错,原因见3:    int u=f();    int v=g(3);    int f()    {        return 11;     }    int g(int value)    {        return value*10;    }    void printf()    {        print("boolean "+bool);        print("char "+c);        print("byte "+b);        print("short "+s);        print("int "+i);        print("long "+l);        print("float "+f);        print("double "+d);        print("String "+str);        print("A "+haha);        print();        print(u);        print(v);    }    public static void main(String[] args)    {        H ob=new H();        ob.printf();    }                  } 

输出:
boolean true
char a
byte 1
short 2
int 3
long 4
float 1.1
double 2.2
String hello world
A net.mindview.A@5e91993f

11
30

注:不管你是在定义类的成员变量时直接为该变量赋值,还是自动调用构造函数为成员变量赋值。程序在运行时,第一步做的是为你的所有的成员变量赋默认值,然后当你是直接为指定成员变量赋值时,程序会在已经为所有成员变量赋过默认值的基础上再为成员变量重复赋一次该值。如果你是在构造函数中为成员变量赋值,那程序会在已经为所有成员变量赋过默认值的基础上再为构造函数中指定的成员变量赋一次值。总之,这种一开头就为类中所有成员变量赋值的自动化进行是不能阻止的。这种赋默认值的手段保证了整个类中成员变量的合法性,所以不管你在构造函数中有没有为一些成员变量赋值都不会导致程序的错误,因为这些成员变量在最开始已经有了安全性的保障。

package net.mindview;import static net.mindview.util.Print.*;//该类的的成员变量先被赋默认值,然后依次为所有的成员变量赋值(本代码是通过调用构造函数为成员变量赋值),赋值顺序为代码的先后顺序,//尽管在成员变量中穿插着方法的定义,也会先依次为成员变量以上面说的那种方式赋值。//类的成员变量会在该类的方法调用之前完成初始化等赋值操作。class A{    A(int i)    {        print(i);    }}public class H{       A a1=new A(1);    void f()    {        print("正在调用f()");    }    A a2=new A(2);    H()    {        A a3=new A(33);    }    A a3=new A(3);    public static void main(String[] args)    {        H h=new H();//在调用构造函数之前,先为所有成员变量赋默认值(int赋值为0),然后因为这里是为成员变量直接赋值(给A类的变量赋值为new A(),所以又这样为指定成员变量赋了一次值。        h.f();     //接上一行:之后再调用该类的构造函数H()    }                  }             

输出:
1
2
3
33
正在调用f()

不得不的说下面这段代码不好理解,我看了3遍而且将变量名字简写,虽能够看写出程序的输出内容,但依旧不能完全理解作者写的这段代码的行为与目的。不过我们可以从下面这段代码中提取一些知识点。

package net.mindview;import static net.mindview.util.Print.*;//main函数是静态函数,也就是不用创建对象能直接被调用。所以在main所在类中,在调用main之前,它所在类的成员变量应进行相关初始化(重复很多遍了,就两步:1赋默认值,2根据直接赋值或者构造函数再对成员变量赋一次值)//所以在main之前要按先后顺序依次执行   static B b=new B();     static C c=new C();//对于static B b=new B(); 首先它很明显调用了构造函数,但是调用函数之前要对该类的成员变量赋值(2步走战略) 而类B中的成员变量为 static A a1=new A(1);   static A a2=new A(2); //因为两个都是静态变量所以依次赋值即可。//但是在static C c=new C();执行时,没错我们还是要对它的成员变量赋值,但是对它的成员变量赋值是又很多说法的,倾特别注意这里。//类C中的成员变量按顺序依次为:   A a3=new A(3);  static A a4=new A(4);   static A a5=new A(5);//但是呢,要先调用静态变量!!静态变量按循序进行,即先执行static A a4=new A(4); static A a5=new A(5); 再执行A a3=new A(3);//再main所在类的成员变量初始化后,就要执行mian()里面的内容了//print("用 new C()创建一个新对象"); 这句没问题//但是new C();就有问题了 !!请注意这里!!同样是调用方法之前要对对象中的成员变量进行初始化,但是静态的成员函数只占用一个空间,所以在初次赋值之后以后便不再需要赋值。//也就是在初始化成员变量部分只执行了 A a3=new A(3);class A{    A(int i)    {        print("调用构造函数A(),参数是"+i);    }    void f1(int i)    {        print("正在调用类A中的方法f1(),参数是"+i);    }}class B{    static A a1=new A(1);    B()    {        print("调用构造函数B()");        a2.f1(1);       }    void f2(int i)    {        print("调用类B的方法f2(),参数是"+i);    }    static A a2=new A(2); }class C{    A a3=new A(3);    static A a4=new A(4);    C()    {        print("调用构造函数C()");        a4.f1(2);    }    void f3(int i)    {        print("调用类C中的方法f3(),参数是"+i);    }    static A a5=new A(5);}public class H{       public static void main(String[] args)    {        print("用 new C()创建一个新对象");        new C();        print("用new C()创建一个新对象");        new C();        b.f2(1);        c.f3(1);    }    static B b=new B();    static C c=new C();}   

输出:
调用构造函数A(),参数是1
调用构造函数A(),参数是2
调用构造函数B()
正在调用类A中的方法f1(),参数是1
调用构造函数A(),参数是4
调用构造函数A(),参数是5
调用构造函数A(),参数是3
调用构造函数C()
正在调用类A中的方法f1(),参数是2
用 new C()创建一个新对象
调用构造函数A(),参数是3
调用构造函数C()
正在调用类A中的方法f1(),参数是2
用new C()创建一个新对象
调用构造函数A(),参数是3
调用构造函数C()
正在调用类A中的方法f1(),参数是2
调用类B的方法f2(),参数是1
调用类C中的方法f3(),参数是1

**注:
1在首次访问一个类的静态变量时
2在首次访问一个类的非静态变量时
3在首次访问一个类的非静态方法时
4在首次访问一个类的静态方法时
都会先对成员变量进行初始化处理。**

package net.mindview;import static net.mindview.util.Print.*;//在类的静态成员被调用前要进行该类中成员变量的初始化...class A{    A()    {        print("调用类A的构造函数A()");    }    void f()    {        print("调用类A的方法f()");    }}class B{    static A a1;    static A a2;    static    {        a1=new A();        a2=new A();    }}public class H{       public static void main(String[] args)    {        B.a1.f();    }}   

输出:
调用类A的构造函数A()
调用类A的构造函数A()
调用类A的方法f()

上面的代码可以改写为以下这种形式:

class A{    A()    {        print("调用类A的构造函数A()");    }    void f()    {        print("调用类A的方法f()");    }}public class H{       public static void main(String[] args)    {        a1.f();    }    static A a1=new A();    static A a2=new A();}  

输出:
调用类A的构造函数A()
调用类A的构造函数A()
调用类A的方法f()

知识点:
java允许将多个静态变量初始化动作组成一个特殊的”静态块”,就像这样:

    static int i;    static String str;    static    {        i=1;        str="12345";    }

尽管上面的代码看上去像方法,但它实际上只是一段跟在static关键字后面的代码,与其他静态化初始动作一样,这段代码只执行一次。

练习题:

package net.mindview;import static net.mindview.util.Print.*;//编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另一个在静态模块中初始化。现在,加入静态方法以打印出两个字段值。请证明他们都会在//被使用之前完成初始化动作class A{    static void printhh()    {        print(str1);        print(str2);    }    static String str1="I love java";    static String str2;    static    {        str2="so much";    }}public class H{       public static void main(String[] args)    {        A.printhh();    }}                  

输出:
I love java
so much

package net.mindview;import static net.mindview.util.Print.*;class Mug{    Mug()    {        print("Mug()");    }}class Mugs{    Mug m1;    Mug m2;    {        m1=new Mug();        m2=new Mug();        print("m1 m2已被初始化");    }    Mugs()    {        print("Mugs()");    }    Mugs(int i)    {        print("Mugs(int)");    }    void f()    {        print("我是来做测试工作的");    }}public class H{       public static void main(String[] args)    {        Mugs hh1=new Mugs();        hh1.f();        Mugs hh2=new Mugs(1);        hh2.f();    }}   

输出:
Mug()
Mug()
m1 m2已被初始化
Mugs()
我是来做测试工作的
Mug()
Mug()
m1 m2已被初始化
Mugs(int)
我是来做测试工作的

注代码中的{}用来初始化每一个对象的费静态变量,这种结构和static{}很像。

===98页练习15未做,以下未看

原创粉丝点击