我在学习java中做的笔记,希望对大家有帮助。
1.关于static的初始化顺序
class bowl {
bowl(int marker) {
system.out.println("bowl(" + marker + ")");
}
void f(int marker) {
system.out.println("f(" + marker + ")");
}
}
class table {
static bowl b1 = new bowl(1);
table() {
system.out.println("table()");
b2.f(1);
}
void f2(int marker) {
system.out.println("f2(" + marker + ")");
}
static bowl b2 = new bowl(2);
}
class cupboard {
bowl b3 = new bowl(3);
static bowl b4 = new bowl(4);
cupboard() {
system.out.println("cupboard()");
b4.f(2);
}
void f3(int marker) {
system.out.println("f3(" + marker + ")");
}
static bowl b5 = new bowl(5);
}
public class staticinitialization {
public static void main(string[] args) {
system.out.println(
"creating new cupboard() in main");
new cupboard();
system.out.println(
"creating new cupboard() in main");
new cupboard();
t2.f2(1);
t3.f3(1);
}
static table t2 = new table();
static cupboard t3 = new cupboard();
} ///:~
输出结果为:
bowl(1)
bowl(2)
table()
f(1)
bowl(4)
bowl(5)
bowl(3)
cupboard()
f(2)
creating new cupboard() in main
bowl(3)
cupboard()
f(2)
creating new cupboard() in main
bowl(3)
cupboard()
f(2)
f2(1)
f3(1)
1.首先运行static table t2= new table();定义一个table型的对象t2,在table内又先初始化 b1, 此时调用bowl方法,输出bowl(1);然后回到table内初始化b2,再次调用bowl,输出bowl(2)。将table 内的static初始化完后才开始初始化table类中的table方法,输出table();接着执行b2.f(1), 输出f(1);
2.然后运行static cupboard t3=new cupboard(); 定义了一个cupboard型的对象t3,再cupboard内首先初始化b4;调用bowl方法,输出bowl(4),然后回到cupboard内初始化b5,输出bowl(5),接着初始化b3, 输出bowl(3),接着输出cupboard().然后调用f方法输出f(2);
3.接着开始执行main方法, 首先输出creating new cupboard() in main , 这是遇到new cupboard();进入类cupboard,先运行bow b3=new bowl(3), 输出bowl(3), 接着输出cupboard(),然后运行b2.f(2),输出f(2).
4.然后回到main方法内,首先输出creating new cupboard() in main,又遇到了new cupboard(), 如上所述,输出bowl(3),输出cupboard(), 输出f(2).
5.下面就是运行t2.f2(1); 因为前面已经定义好了t2,此时直接调用t2 的f2方法就行,再table内调用f2方法输出f2(1);运行t2.f3(1)也一样,调用cupboard内的方法f2就输出了f3(1).
关于对象的初始化我来说几句吧,说错了的话,不好意思啊:
对于初始化主要包含这几方面:static 变量 、non-static变量、构造函数、new对象建立。
1、static 变量的初始化:当pulic class 被loadin(栽入)的时候,就开始对static变量初始化了,因为static 变量的refrence是存储在static storage(静态存储空间)中。此时不对non-static变量和构造函数初始化,因为还没有对象的产生,只是把某个型别loadin。注意对于static变量只初始化1次,当有新的对象产生时,他并不会重新被初始化了,也就是他的refrence已经固定,但他的值是可以改变的。
2、当有对象产生时,开始对此class(型别)内的non-static变量进行初始化,然后再初始化构造函数。产生已初始化的object对象。
3、按要求顺序执行其它函数。
4、对有继承的class(型别)来说:derivedclass2、derivedclass1、baseclass;因为他们之间的继承关系,所以要想laodin derivedclass2,必须先loadin derivedclass1,如果想laodin derivedclass1,则先loadin baseclass。也就是说,laodin 顺序为:baseclass、derivedclass1、deriveclass2……,每当loadin 一个class时,则按"第一条"进行初始化(初始化该class内的static变量)。
5、对有继承的class 当用new产生对象时,会按baseclass、derivedclass1、deriveclass2……的顺序,每个class内再按"第二条"进行初始化。注意derived class 的构造函数,一定要满足baseclss可初始化。
总体思想:static变量……non-static变量……构造函数。
***********************************************************************************************
2.
静态变量的初始化问题。
class value{
static int c=0;
value(){
c=15;
}
value(int i){
c=i;
}
static void inc(){
c++;
}
}
class count{
public static void prt(string s){
system.out.println(s);
}
value v=new value(10);
static value v1,v2;
static{
prt("v1.c="+v1.c+" v2.c="+v2.c);
v1=new value(27);
prt("v1.c="+v1.c+" v2.c="+v2.c);
v2=new value(15);
prt("v1.c="+v1.c+" v2.c="+v2.c);
}
public static void main(string[] args){
count ct=new count();
prt("ct.c="+ct.v.c);
prt("v1.c="+v1.c+" v2.c="+v2.c);
v1.inc();
prt("v1.c="+v1.c+" v2.c="+v2.c);
prt("ct.c="+ct.v.c);
}
}
运行结果如下:
v1.c=0 v2.c=0
v1.c=27 v2.c=27
v1.c=15 v2.c=15
ct.c=10
v1.c=10 v2.c=10
v1.c=11 v2.c=11
ct.c=11
class中的所有变量一定会在调用任何一个函数(包括构造函数)之前完成初始化.
******************************************************************************************
3.有关sstr1==sstr2 sstr1.equals(sstr2) sstr1.compareto(sstr2)疑惑
/*
* 其中sstrl==str2 与 sstr1.equals(sstr2);是怎么回事,同一个对象就应该相等呀,
*/
import java.io.*;
class equalstest {
public static void main(string args[])throws ioexception {
string sstr1,sstr2;
sstr1="using java language";
sstr2=sstr1;
system.out.println("string1:"+sstr1);
system.out.println("string2:"+sstr2);
system.out.println("same objext? "+(sstr1==sstr2));
sstr2=new string(sstr1);
system.out.println("string1:"+ sstr1);
system.out.println("strint2:"+ sstr2);
system.out.println("same object? "+(sstr1==sstr2)); // (1)
system.out.println("same value? "+sstr1.equals(sstr2)); // (2)
system.out.println("same value? "+sstr1.compareto(sstr2)); //(3)
system.in.read();
}
}
运行结果是:
string1:using java language
string2:using java language
same objext? true
string1:using java language
strint2:using java language
same object? false
same value? true
same value? 0
解答:
sstr1.equals(sstr2):返回值是一个boolean值,它比较两个字符串的值是否相等;
sstr1.compareto(sstr2):返回值是一个整数,compareto()不仅比较大小,还确定了排列的顺序。
如果sstr1大于sstr2,返回一个正整数,如果sstr1小于sstr2,返回一个负整数,如果sstr1等于sstr2,返回0。
sstr1="using java language"; //初始化一个字符串
sstr2=new string(sstr1); //新建一个字符串对象,两者的值一样,但是却指向不同的内存空间
//所以sstr1==sstr2 返回的是false,如果要比较两个字符串的内容是否相等,要用equals方法
sstr1==sstr2不仅比较其内容是否相同,还比较其是否是指向同一个内存地址的。
sstr1="using java language";
sstr2=sstr1;
system.out.println("string1:"+sstr1);
system.out.println("string2:"+sstr2);
system.out.println("same objext? "+(sstr1==sstr2));
这里sstr1="using java language";先初始化一个字符串
sstr2=sstr1;这一步,将sstr2也指向了sstr1的地址,即同一个字符串"using java language"
所以,此时,不仅内容相同,而且连地址也一样,于是返回true。
创建一个string类的对象,给它初始化的时候应该是字串,所以你new一个之后,虽然初始化用的是sstr1,但是只是传递的只是sstr1的值。所以还是不同的两个对象
新建一个字符串对象,两者的值一样,但是却指向不同的内存空间
sstr1==sstr2不仅比较其内容是否相同,还比较其是否是指向同一个内存地址的。
sstr1.equals(sstr2):返回值是一个boolean值,它比较两个字符串的值是否相等;
sstr1.compareto(sstr2):返回值是一个整数,compareto()不仅比较大小,还确定了排列的顺序。
**********************************************************************************************
4.有关日期的显示问题
import java.util.date;
import java.text.*;
class todaydate {
public static void main(string[] args){
dateformat defaultdata= dateformat.getdateinstance();
system.out.println(defaultdata.format(new date()));
dateformat shorttime= dateformat.gettimeinstance(dateformat.short);
system.out.println(shorttime.format(new date()));
dateformat longtimestamp=
dateformat.getdatetimeinstance(dateformat.full,dateformat.full);
system.out.println(longtimestamp.format(new date()));
dateformat myformat=new simpledateformat("yyyy.mm.dd"); //?
system.out.print(myformat.format(new date()));
try {
date leapday=myformat.parse("1985.01.27");
}
catch(parseexception e){}
system.out.println();
}
}
/*
* 2004-10-29
下午12:52
2004年10月29日 星期五 下午12时52分45秒 cst
2004.52.29 /// 怎么显示的是52,而不是月呀?
dateformat myformat=new simpledateformat("yyyy.mm.dd"); 把mm改成mm就可以了
*/
***************************************************************************************
5.有关线程的问题
import java.util.timer;
import java.util.timertask;
public class reminder {
timer timer;
public reminder(int seconds) {
timer = new timer();
timer.schedule(new remindtask(), seconds*1000);
}
class remindtask extends timertask {
public void run() {
system.out.println("times up!");
timer.cancel();
}
}
public static void main (string args[]) {
new reminder(3);
// for(int i=0;i<10000;i++)
// for(int j=0;j<10000;j++);
system.out.println("task scheduled.");
}
}
/*
timer.schedule(new remindtask(), seconds*1000);
task scheduled.
times up!
我把这一句改成
timer.schedule(new remindtask(), seconds*0); 以后显示的是
task scheduled.
times up!
在延迟时间为0的时候与延迟时间为3秒的显示是一样的,我不知道这个程序是怎么调用,
我总觉的是
times up!
task scheduled.
程序改为:
new reminder(0);
for(int i=0;i<10000;i++)
for(int j=0;j<10000;j++); // 延迟时间
结果是:
d:\eclipse\workspace\hello>java reminder
times up!
task scheduled.
*/
*********************************************************************************************
6.
当一个对象被创建时,初始化是以下面的顺序完成的:
1. 设置成员的值为缺省的初始值 (0, false, null)
2. 调用对象的构造方法 (但是还没有执行构造方法体)
3. 调用父类的构造方法
4. 使用初始化程序和初始块初始化成员
5. 执行构造方法体
class a {
int a = f();
int f() {
return 1;
}
}
class b extends a {
int b = 37;
int f() {
return b;
}
}
public class ctordemo4 {
public static void main(string args[]) {
b bobj = new b();
system.out.println(bobj.a);
system.out.println(bobj.f());
}
}
0
37
执行顺序应该是:
1. 从heap中分配a, b以及method指针, class指针的内存
2. 将a, b 初始化为数据default值,如int为0, 对象指针为null.
3. 调用b(), 注意:未进入构造函数体,传参数用。
4. 调用a().
5. 执行a()函数体,返回.
6. 对a initialize, 调用b().f,此时b=0!!!!!!!!
7. 执行b()函数体,返回
8. 对b initialize, 调用b=37
9. bobj指向heap中最终创建完成的b对象.
