[敏捷JAVA读书笔记-java基础部分] 第四章

1、类变量和类方法


对象是由属性和行为构成,属性对应java类中的 成员变量(实例变量和类变量),行为对应类中的方法。

java类的状态是由他的成员变量的状态决定的。

在java中被声明为static的成员变量和成员方法是类变量和类方法,在类加载的时候即被初始化。存放在方法区。

没有被声明为static的成员变量和成员方法是实例变量和实例方法。实例变量在new 一个对象的时候初始化。实例方法应该是啥时候调用,啥时候初始化。

实例变量存放在堆区,他的生命周期与对象的相同。调用实例方法的时候,虚拟机会在栈区开辟一块单独的内存空间,因此实例方法内的变量是现成安全的,执行完毕后,虚拟机会收回这块内存。


2、更多初始化的内容


执行一个类的时候,jvm首先找到类名.class,而后装载,加载进内存,这个时候在内存中会造成一个类对象,用来表明这个类(因此咱们用对象.class.getClassName()的时候老是获得相同的值,这个就是类对象的名字),而后进行静态初始化,初始化类中的全部成员变量以及成员函数还有static块。
静态初始化只进行一次:当静态变量或者方法被调用,类加载的时候进行!静态的东西是属于类的。而不是属于对象的,过分的使用静态是很危险的!确信使用静态的时候才使用静态!

java初始化的时候一个基本的原则:
先静态后动态
先定义初始化后构造函数。
package com;

class A{
A(String who){
System.out.println("create A by "+who);
}
}

class B{
A a = new A("B");

B(String who){
System.out.println("create B by "+who);
}
}

class C{
static {
A a = new A("C static");
}

C(String who){
System.out.println("create C by "+who);
}
}

class Init{

static B b = new B("Init");
static C c = new C("Init");
//C c = new C("Init");

public static void main(String [] args){

}
}
保存为Init.java
编译:javac com/Init.java
执行:java com/Init

当你在cmd命令行窗口上敲入
java com/Init 的时候,
一、启动java虚拟机。
二、到com下面查找Init.class。
三、若是有就加载进jvm,没有就跑出一个nofound的异常。
四、jvm将Init.class加载到内存,造成类对象,而后开始静态初始化。执行
static B b = new B("Init");
五、而后加载B.class进内存
六、而后执行new B("Init");的操做。即调用B的构造函数。
七、根据先定义初始化后构造函数的顺序,会先执行
A a = new A("B");
八、jvm加载A进内存,并造成A的类对象。而后调用A的构造函数建立A 。
九、而后调用B的构造函数建立B。
十、而后执行
static C c = new C("Init");,重复上面的顺序。
因此最后的打印结果是:
create A by B
create B by Init
create A by C static
create C by Init

注意:若是把
static C c = new C("Init");改为:C c = new C("Init");打印的结果应该是:
create A by B
create B by Init

由于咱们并无用调用C的构造函数去new一个C出来,而没有static修饰的变量不是类变量,并不在类加载的时候初始化,他是在调用此类的构造函数以前被初始化。

再来看一个java中比较有趣的东西:

package com;

class Some{
int i;

boolean b;

char c;

double d;

int k = f();

int u = g(k);

{
Init init = new Init();
}


int f(){
return 10;
}

int g(int u){
if(u==10)
return 100;
return 0;
}

void print(){
System.out.println("i:"+i+" k:"+k +" u:"+u+" b:"+b+" c:"+c+" d:"+d);
if(c=='\0'){
System.out.println("c is '\0'");
}

}
public static void main(String [] args){
Some some = new Some();
some.print();
}
}


执行结果是:

create A by B
create B by Init
create A by C static
create C by Init
i:0 k:10 u:100 b:false c: d:0.0
c is ' '

java容许在定义初始化的时候调用函数。
也容许使用{}这样的东西来作一些特别的事情。

3、new String("a string")到底干了什么?

String str = new String("a string");到底作了什么?

一、an object of String is create //在堆区内建立一个String类型的对象
二、the object is initialized by "a string"//用a string 初始化它
三、a variable as handle to String is create //在栈区内建立一个句柄,也就是引用变量str
四、the value of the handle variable is assign to the object//这个str指向堆区内的String对象

4、传值仍是传引用

java中函数传递参数通通能够理解为是传值!不过要搞清楚,这个值里面是什么东西,是对象的引用仍是基本的数据类型。

class Letter{
char c = 'a';
}
class passObject{
static void f(Letter y){
y.c = 'z';//
y.c = 'z' 就是改变这个对象的成员变量c的值,因此,x.c = ‘z’
}
public static void main(String [] args){
Letter x = new Letter();//建立一个Letter类型的变量x,x中存储Letter对象的首地址好比0x001....
f(x);//至关于作了 y = x的操做,这个时候y与x指向同一个对象

System.out.println(x.c);
}
}

x是一个引用,他是Letter类型的变量,他存储Letter的对象的首地址好比多是0x001(也就是他是指向Letter对象的句柄),这句话就是把对象的引用付给y 就至关于作了 y = x 操做,这个时候y与x指向同一个对象。
相关文章
相关标签/搜索