从事Java开发也已经差不多快一年了,说来惭愧,有很多很基础的知识到现在才弄明白。废话不多说,我们从几个小例子说起。

assert & transient 关键字
volatile 关键字

程序清单:

Student.java

package com.ue.zm.test.po; 
import java.io.Serializable; 
public class Student implements Serializable { 
private static final long serialVersionUID = 3976535276585232757L; 
private String username; 
private transient String password; 
public Student(String username, String password) { 
  super(); 
  this.username = username; 
  this.password = password; 
  assert !"".equals(username); 
//当被 assert 修饰的值为false的时候抛出"java.lang.AssertionError" 注意是错误而非异常 
/*关于这一点,专家组也进行了长期的讨论。Error代表一些异常的错误,通常是不可以恢复的,而RuntimeException强调该错误在运行时才发生的特点。AssertionError通常为非常关键的错误,这些错误往往是不容易恢复的,而且assertion机制也不鼓励程序员对这种错误进行恢复。因此,为了强调assertion的含义,Java专家小组选择了让AssertError为Error的子类。 
PS:如果你能看到这一行,说明你还挺细心的。呵呵~~ 
*/
} 
public String getUsername() { 
  return username; 
} 
public void setUsername(String username) { 
  this.username = username; 
} 
public String getPassword() { 
  return password; 
} 
public void setPassword(String password) { 
  this.password = password; 
} 
public String toString(){ 
  return username + ":" + password; 
} 
}



MainTest.java


package com.ue.zm.test; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import com.ue.zm.test.po.Student; 
/** 
* 
* @作者: 赵明 
* @类作用:测试java序列化对象transient关键字和assert关键字功能。 
* @日期:Jun 9, 2008 
* @时间:1:55:31 AM 
*/ 
public class MainTest { 
private static String FIlE_PATH_C = "c:/data.dat"; 
public static void writer() { 
  try { 
   Student stu = new Student("","123456"); 
   //这里此时!"".equals(username)为fasle,会抛出AssertionError错误。 
   //而当给一个"zhaoming"时就使!"".equals(username)为true。 
   FileOutputStream fos = new FileOutputStream(new File(FIlE_PATH_C)); 
   ObjectOutputStream oos = new ObjectOutputStream(fos); 
   oos.writeObject(stu); 
  } catch (FileNotFoundException e) { 
   e.printStackTrace(); 
  } catch (IOException e) { 
   e.printStackTrace(); 
  } 
} 
public static void main(String[] args) { 
  writer(); 
  try { 
   FileInputStream fis = new FileInputStream(new File(FIlE_PATH_C)); 
   ObjectInputStream ois = new ObjectInputStream(fis); 
   Student stu = (Student)ois.readObject(); 
   System.out.println(stu); 
  } catch (FileNotFoundException e) { 
   e.printStackTrace(); 
  } catch (IOException e) { 
   e.printStackTrace(); 
  } catch (ClassNotFoundException e) { 
   e.printStackTrace(); 
  } 
} 
}



本例子要执行需要用到java虚拟机的一个参数 -ea (其他参数详见:点我打开该内容)



以下是命令行执行MainTest类的结果:

C:\workspace\Test\bin>java -ea com.ue.zm.test.MainTest 

Exception in thread "main" java.lang.AssertionError 

 at com.ue.zm.test.po.Student.<init>(Student.java:13) 

 at com.ue.zm.test.MainTest.writer(MainTest.java:24) 

 at com.ue.zm.test.MainTest.main(MainTest.java:35) 

C:\workspace\Test\bin>java -ea com.ue.zm.test.MainTest 

zhaoming:null 

C:\workspace\Test\bin>

从这个小例子我们可以得到两个重要的信息:



1、被assert关键字修饰的对象或值,可以在程序运行的时候动态的调整检测与否,这个取决与jvm的参数,而不用测试和发布软件的时候编写两个版本的程序。虽然那样做可以提高性能,但java没有这样做的目的在于,付出一点点性能上的损失(java开发组称:微乎其微的性能损失)可以换得灵活的调整检测比开发时编写繁多的测试代码要划算的多的多。



2、被transient关键字修饰的对象或者值,在序列化的时候不被保存到字节码中,这样可以使用到一些重要的信息不被反序列化时被显示出来,比如密码等一些敏感信息。



这两个关键字都是java 1.4 以后才加入的新功能 ,故不被该版本以前的jdk支持,也通不过编译。使用中应当注意。



PS:关注Java,关注互联网技术。学习永无至尽。



================ volatile关键字 ====================


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class Singleton {
	private Lock lock = new ReentrantLock();
	private volatile Singleton uniqueInstance;
	private String userName;
	private transient String passWord;
	private Singleton() {
	}
	public Singleton getInstance(){
		if (uniqueInstance == null) {
			try {
				lock.lock();
				if (uniqueInstance == null) {
					uniqueInstance = new Singleton();
				}
			}finally{
				lock.unlock();
			}
		}
		return uniqueInstance;
	}
}