|
![]() |
名片设计 CorelDRAW Illustrator AuotoCAD Painter 其他软件 Photoshop Fireworks Flash |
|
我在学习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("Time\\\'s 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. Time\\\'s up! 我把这一句改成 timer.schedule(new RemindTask(), seconds*0); 以后显示的是 Task scheduled. Time\\\'s up! 在延迟时间为0的时候与延迟时间为3秒的显示是相同的,我不知道这个程序是怎么调用, 我总觉的是 Time\\\'s 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 Time\\\'s 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对象. 返回类别: 教程 上一教程: 深入分析java中类的构造 下一教程: java编码中的一些经验和教训 您可以阅读与"java学习笔记"相关的教程: · Java的“对象思想”学习笔记[二] · Java 网络编程---I/O部分学习笔记整理1 · java虚拟机学习笔记1 · java学习笔记7--Polymorphism · 《Effective Java》学习笔记(3) |
![]() ![]() |
快精灵印艺坊 版权所有 |
首页![]() ![]() ![]() ![]() ![]() ![]() ![]() |