??xml version="1.0" encoding="utf-8" standalone="yes"?> public static void main(String[] args) { c=c+d; public static void main(String[] args) { System.out.println("Hello World"); } } 此外Q我对于staticQpublicQprivateQExceptionQtry{ }catch {}finally{}{等一开始都不是很懂Q都是把参考书上面的例子运行成功,然后开始破坏它Q不断的Ҏ(gu)自己心里面的疑问来重新改写程序,看看能不能运行,q行出来是个什么样子,是否可以得到预期的结果。这栯然比较费旉Q不q一个例子程序这样反复破坏几ơ之后。我对q个相关的知识彻底学通了。有时候甚x意写一些错误的代码来运行,看看能否得到预期的运行错误。这样对于编E的掌握是及(qing)其深ȝ。其中特别值得一提的?a target="_bank">JDK有一个非常棒的调试功?verbose?/p>
java –verbose javac –verbose 以及(qing)其它很多JDK工具都有q个选项 -verbose 可以昄在命令执行的q程中,JVM都依ơ加载哪里ClassQ通过q些宝贵的调试信息,可以帮助我们分析出JVM在执行的q程中都q了些什么。另外,自己在学?fn)过E中Q写的很多的q种破坏例程Q应该有意识的分门别cȝ保存下来Q在工作中积累的典型例程也应该定期整理,日积月篏Q自己就有了一个代码库了。遇到类似的问题Q到代码库里?Copy & Paste QSearch & ReplaceQ就好了Q极大提高了开发速度。最理想的情冉|把一些通用的例E自己再抽象一层,形成一个通用的类库,装好。那么可复用性就更强了。所以我觉得其实不是特别需要例E的Q自己写的破坏例E就是最好的例子Q如果你实在对自己写的代码不攑ֿ的话Q我强烈推荐你看看JDK基础cd的Java源代码。在JDK安装目录下面?x)有一个src.zipQ解开来就可以完整的看到整个JDK基础cdQ也是rt.jar的Java源代码,你可以参考一?a target="_bank">Sun是怎么写JavaE序的,规范是什么样子的。我自己在学?fn)Java的类库的时候,当有些地方理解的不是很清楚的时候,或者想更加清晰的理解运作的l节的时候,往往?x)打开相应的类的源代码Q通过看源代码Q所有的问题都会(x)一扫而空?/p>
factory = (ExampleInterface)c.newInstance();
class c = Class.forName(className); factory = (ExampleInterface)c.newInstance();
java的几U数值基本类型:(x)int,short,long,float,double
试代码Q?br />
short x = 100;
long b = 2;
int a = 2;
double y=1.1;
float z=(float) 1.2;
double c=1.1;
float d=(float) 1.2;
a=x+a;
x+=1.1;
b=b+a;
y=y-1;
z=z-1;
c=c+1;
d=d+1;
System.out.println(a);
System.out.println(x);
System.out.println(b);
System.out.println(z);
System.out.println(y);
System.out.println(c);
System.out.println(d);
System.out.println(c);
c=c-d;
System.out.println(c);
d=(float) (d-1.1);
System.out.println(d);
}
q行l果Q?br />
102
101
104
0.20000005
0.10000000000000009
2.1
2.2
4.3000000476837155
2.0999999999999996
1.1
试说明Q?br />
不同cd数据做计时按照计算中最大范围数据类型返回,例如Qa=x+a;(如果负值对象是较小范围的类型就需要强转类型,否则?x)报?
doublecd做加时运精度准,做减q算时有_ֺ偏差Q且和floatcd怺作加减操作都?x)出现精度缺失?br />
+=W号做运不牉|cd转换问题Q按照负值对象的cdq回?br />
]]>
public class HelloWorld {
很多初学者不是很理解Z么mainҎ(gu)一定要q样来定义public static void main(String[] args)Q能不能不这样写?包括我刚学习(fn)Java的时候也有这L(fng)疑问。想知道{案?很简单,你把main改个名字q行一下,看看报什么错误,然后Ҏ(gu)出错信息q行分析;把main的public取掉Q在试试看,报什么错?staticLq能不能q行;不知道mainҎ(gu)是否一定要传一个String[]数组的,把String[]Ҏ(gu)Q改?a target="_bank">int[]Q或者String试试?不知道是否必dargs参数名称的,也可以把argsҎ(gu)别的名字Q看看运行结果如何。我当初学习(fn)Java的时候就是这样做的,把Hello WorldE序反复改了七八ơ,不断q行Q分析运行结果,最后就d明白Z么mainҎ(gu)是这样定义的了?
其中ExampleInterface是Example的接口,可以写成如下形式Q?/p>
class c = Class.forName(“Example”);
q一步可以写成如下Ş式:(x)
String className = "Example";
String className = readfromXMlConfig;//从xml 配置文g中获得字W串
class c = Class.forName(className); factory = (ExampleInterface)c.newInstance(); |
?a target="_bank">JVM的角度看Q我们用关键字new创徏一个类的时候,q个cd以没有被加蝲。但是用newInstance()Ҏ(gu)的时候,必M证:(x)1、这个类已经加蝲;2、这个类已经q接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,q个静态方法调用了启动cd载器Q即加蝲java API的那个加载器?/p>
现在可以看出QnewInstance()实际上是把newq个方式分解Z步,即首先调用Class加蝲Ҏ(gu)加蝲某个c,然后实例化?q样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灉|性,提供l了一U降耦的手段?/p>
最后用最单的描述来区分new关键字和newInstance()Ҏ(gu)的区别:(x)
newInstance: q型。低效率。只能调用无参构造?/p>
new: 强类型。相寚w效。能调用Mpublic构造?/p>
--ObjectOutputStream
ObjectInputStream cL复以前?ObjectOutputStream cd列化后的基本cd数据和对象?
ObjectOutputStream ?ObjectInputStream 分别利用 FileOutputStream ?FileInputStream 能支持应用程序实现对象图象的E_存储?/p>
ObjectInputStream 可用于恢复以前序列化q的对象。另外其它一些情况也使用此类Q诸如用一?Socket 在主机间传递对象时Q?/p>
或在q程通讯pȝ中ؓ(f)实现参数和参变量的通讯而进行对象传递时?
ObjectInputStream 保证从流中创建的图象中的所有对象的cd?Java 虚拟Z出现的类匚w。用标准机制按需装蝲相应cR?
只有支持 java.io.Serializable ?java.io.Externalizable 接口的对象才能从中d。?readObject Ҏ(gu)从该中
d一个对象?Java 的安全造型应该用于获取期望cd。在 Java ? 串和数组都是对象且可当作是序列化q程中的对象?/p>
dӞ它们需要{换ؓ(f)所需cd?
另外基类型也可?DataInput 中的正确Ҏ(gu)从该中d?
对象的缺省逆序列化机制每个域的内Ҏ(gu)复ؓ(f)它被写入时的值和cd。逆序列化q程中忽略申明ؓ(f)暂时的或静态的域?/p>
对其它对象的引用促那些对象必须从流中读取。用引用共享机制正地恢复对象的图象。逆序列化时L分配新对象,
防止重写已存在的对象?
d一个对象同q行一个新对象的构造子cM。ؓ(f)该对象分配的内存初始化ؓ(f)I?NULL)。ؓ(f)非序列化c调用无参构造子Q?/p>
然后序列化cȝ域从该流中恢复,恢复从最接近 java.lang.object 的序列化对象开始,到指定对象结束?
例如d在示例中写入 ObjectOutputStream 中的:(x)
FileInputStream istream = new FileInputStream("t.tmp");
ObjectInputStream p = new ObjectInputStream(istream);
int i = p.readInt();
String today = (String)p.readObject();
Date date = (Date)p.readObject();
istream.close();
c通过实现 java.io.Serializable ?java.io.Externalizable 接口来控制它们的序列化?/p>
实现序列化接口可以对象能保存和恢复它的完整状态,可以使类在写入流和从中d的期间内q行改进?/p>
它自动地遍历对象间的引用Q保存和恢复完整图象。在序列化和逆序列化处理q程中需要特定句柄的可序列化c,
必须实现如下q两个方法:(x)
private void writeObject(java.io.ObjectOutputStream stream)
throws IOException;
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException;
利用 writeObjectmethod Ҏ(gu)一个特D类的对象的状态写入某后Q相应的 readObject Ҏ(gu)负责读取和恢复q些数据?/p>
此方法不必关心状态是属于它的父类q是子类??ObjectInputStream d数据恢复单个域的状态,q将之赋l该对象的恰当域?/p>
使用 DataInput Ҏ(gu)d基本数据cd?/p>
序列化操作对没有实现 java.io.Serializable 接口的对象,不读取或分配它的域倹{非序列化对象的子类可以是序列化的?/p>
在这U情况下Q非序列化类必须有一个无参构造子Q它的域能使用此构造子完成初始化?在此情况下,
子类负责保存和恢复非序列化类的状态。通常情况父类的域是可存储?公有的、包或保护的)Q?/p>
或存在用于恢复它的状态的可用的获取或设|方法?
ObjectInputStream 能获取逆序列化一个对象期间出现的M异常Q一旦出现异常,则放弃读q程?
实现外部接口可以使对象完全控制此对象序列化Ş式的内容和格式?/p>
调用外部接口的方法:(x)writeExternal ?readExternal 保存和恢复对象状态。当一个类实现了这些方法时Q?/p>
它们p使用 ObjectOutput ?ObjectInput Ҏ(gu)的所有方法写入或d它们自己的状态。对象负责管理它出现的相应版本?
ObjectOutputStream
public class ObjectOutputStream
extends OutputStream
implements ObjectOutput, ObjectStreamConstants
c?ObjectOutputStream ?Java 对象中的基本数据cd和图元写入到一?OutputStream 对象中。可使用 ObjectInputStream dq些对象?/p>
另外使用此流对应的文件能存储q些对象。如果该是一个网l通讯,则在另一C机或另一个处理机上可重徏q些对象?
只有支持 java.io.Serializable 接口的对象才能被写入该流。对每个可序列化的对象进行编码,包括相应cȝ名称和标讎ͼ
对象的属性和数组|以及(qing)初始化对象时引用的Q何其它对象等?
使用 writeObject 一个对象写入该。Q一对象Q包括串和数l,均采?writeObject Ҏ(gu)被写入?/p>
也能多个对象或基类型对象写入此。反q来Q必Mq些对象被写入的相同cd和相同顺序,
从相应的 ObjectInputstream 中dq些对象?
基类型也可?DataOutput 中的正确Ҏ(gu)写入此流。串对象也可使用 writeUTF Ҏ(gu)写入?/p>
一个对象的~省序列化机制将写入对象的类Q类标记和所有的非暂时的和非静态的属性倹{?/p>
其它对象(除暂时的或静态的属?的引用也促使以上这些对象被写入?使用׃n机制Q对单一对象的多ơ引用进行编码,
以至对象的图元能被存储ؓ(f)与它原来写入时有相同的Ş状?
例如写入一个对象,此对象能?ObjectInputStream 中读出:(x)
FileOutputStream ostream = new FileOutputStream("t.tmp");
ObjectOutputStream p = new ObjectOutputStream(ostream);
p.writeInt(12345);
p.writeObject("Today");
p.writeObject(new Date());
p.flush();
ostream.close();
在序列化处理q程中需要特定句柄的c,必须使用如下q些恰当的标记实现特定的Ҏ(gu)Q?
private void readObject(java.io.ObjectInputStream stream)
throws IOException, ClassNotFoundException;
private void writeObject(java.io.ObjectOutputStream stream)
throws IOException
writeObject Ҏ(gu)负责写特定类的对象的状态,以相应?readObject Ҏ(gu)能存储它?/p>
此方法不必关心写入对象的父类或子cȝ状态。?writeObject Ҏ(gu)或基本类型支持的 DataOutput
Ҏ(gu)每个域的状态保存到 ObjectOutputStream 中?
序列化操作不能输出没有实?java.io.Serializable 接口的Q一对象的域。非序列化对象的子类可以是序列化的?
在这U情况下Q非序列化类必须有一个无参构造子Q它的域能被初始化?在此情况下,子类负责保存和恢复非序列化类的状态?
通常情况父类的域是可存储?公有的、包或保护的)Q或存在用于恢复它的状态的可用的获取或设|方法?
实现抛出 NotSerializableException 异常?writeObject ?readObject Ҏ(gu)能阻止一个对象的序列化?
ObjectOutputStream 获取这个异常,q放弃这个序列化q程。实现外部接口可以对象完全控制此对象序列化形式的内容和格式?
调用外部接口的方法:(x)writeExternal ?readExternal 保存和恢复对象状态。当一个类实现了这些方法时Q?/p>
它们p使用 ObjectOutput ?ObjectInput Ҏ(gu)的所有方法写入或d它们自己的状态。对象负责管理它出现的相应版本?
import java.io.*;
import java.util.*;
public class Logon implements Serializable {
private Date date = new Date();
private String username;
private transient String password;
Logon(String name, String pwd) {
username = name;
password = pwd;
}
public String toString() {
String pwd = (password == null) ? "(n/a)" : password;
return "logon info: \n " + "username: " + username + "\n date: " + date + "\n password: " + pwd;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Logon a = new Logon("Morgan", "morgan83");
System.out.println( "logon a = " + a);
ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));
o.writeObject(a);
o.close();
int seconds = 5;
long t = System.currentTimeMillis() + seconds * 1000;
while(System.currentTimeMillis() < t) ;
ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));
System.out.println( "Recovering object at " + new Date());
a = (Logon)in.readObject();
System.out.println("logon a = " + a);
}
}
cLogon是一个记录登录信息的c,包括用户名和密码。首先它实现了接口SerializableQ这标志着它可以被序列化?/p>
之后再mainҎ(gu)里ObjectOutputStream o = new ObjectOutputStream( new FileOutputStream("Logon.out"));
新徏一个对象输出流包装一个文件流Q表C对象序列化的目的地是文件Logon.out。然后用Ҏ(gu)writeObject开始写入?/p>
惌q原的时候也很简单ObjectInputStream in = new ObjectInputStream( new FileInputStream("Logon.out"));
新徏一个对象输入流以文件流Logon.out为参敎ͼ之后调用readObjectҎ(gu)可以了?/p>
?在java.utilq个包里面提供了一个Random的类Q我们可以新Z个Random的对象来产生随机敎ͼ他可以生随机整数、随机float、随机doubleQ随机longQ这个也是我们在j2me的程序里l常用的一个取随机数的Ҏ(gu)?/font>
?在我们的SystemcM有一个currentTimeMillis()Ҏ(gu)Q这个方法返回一个从1970q?????U到目前的一个毫U数Q返回类型是longQ我们可以拿他作Z个随机数Q我们可以拿他对一些数取模Q就可以把他限制在一个范围之内啦
其实在Random的默认构造方法里也是使用上面W三U方法进行随机数的生的
对于Ҏ(gu)二中的RandomcL以下说明Q?
java.util.RandomcL两种方式构徏方式Q带U子和不带种?/font>
不带U子Q?/font>
此种方式会(x)q回随机的数字,每次q行l果不一?/font>
public class RandomTest {
public static void main(String[] args) {
java.util.Random r=new java.util.Random();
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
带种子:(x)
此种方式Q无论程序运行多次Q返回结果都是一L(fng)
public static void main(String[] args) {
java.util.Random r=new java.util.Random(10);
for(int i=0;i<10;i++){
System.out.println(r.nextInt());
}
}
两种方式的差别在?/font>
(1) 首先h开Java DocQ我们会(x)看到Randomcȝ说明Q?/font>
此类的实例用于生成伪随机数流Q此cM?48 位的U子Q该U子可以使用U性同余公式对其进行修改(请参?Donald Knuth 的《The Art of Computer Programming, Volume 2》,W?3.2.1 节)(j)?/font>
如果用相同的U子创徏两个 Random 实例Q则Ҏ(gu)个实例进行相同的Ҏ(gu)调用序列Q它们将生成q返回相同的数字序列。ؓ(f)了保证实现这U特性,我们为类Random指定了特定的法。ؓ(f)?Java 代码的完全可UL性,Java 实现必须让类 Random 使用此处所C的所有算法。但是允?Random cȝ子类使用其他法Q只要其W合所有方法的常规协定卛_?/font>
Java Doc对Randomcdl解释得非常明白Q我们的试也验证了q一炏V?/font>
(2) 如果没有提供U子敎ͼRandom实例的种子数是当前旉的毫U数Q可以通过System.currentTimeMillis()来获得当前时间的毫秒数。打开JDK的源代码Q我们可以非常明地看到q一炏V?/font>
/**
* Creates a new random number generator. Its seed is initialized to
* a value based on the current time:
* Random() { this(System.currentTimeMillis()); }java.lang.System#currentTimeMillis()
*/
public Random() { this(System.currentTimeMillis()); }
另外Q?
random对象的nextInt(),nextInt(int n)Ҏ(gu)的说明:(x)
int nextInt()
q回下一个伪随机敎ͼ它是此随机数生成器的序列中均匀分布?int 倹{?/font>
int nextInt(int n)
q回一个伪随机敎ͼ它是从此随机数生成器的序列中取出的、在 0Q包括)(j)和指定|不包括)(j)之间均匀分布?int倹{?br />
源引自:(x)http://okone96.itpub.net/post/9033/231699