现在的位置: 首页 > 综合 > 正文

Java中的transient,volatile和strictfp关键字

2018年04月18日 ⁄ 综合 ⁄ 共 3178字 ⁄ 字号 评论关闭

Java中的transient,volatile和strictfp关键字 
    如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。例如: 

Java代码  收藏代码
  1. class T {  
  2.    transient int a;  //不需要维持  
  3.    int b;  //需要维持  
  4. }  


    这里,如果T类的一个对象写入一个持久的存储区域,a的内容不被保存,但b的将被保存。 
    volatile修饰符告诉编译器被volatile修饰的变量可以被程序的其他部分改变。在多线程程序中,有时两个或更多的线程共享一个相同的实例变量。考虑效率问题,每个线程可以自己保存该共享变量的私有拷贝。实际的变量副本在不同的时候更新,如当进入synchronized方法时。 
    用strictfp修饰类或方法,可以确保浮点运算(以及所有切断)正如早期的Java版本那样准确。切断只影响某些操作的指数。当一个类被strictfp修饰,所有的方法自动被strictfp修饰。 
    strictfp的意思是FP-strict,也就是说精确浮点的意思。在Java虚拟机进行浮点运算时,如果没有指定strictfp关键字时,Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令你满意。而一旦使用了strictfp来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。因此如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。 
你可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字,例如下面的代码: 

1. 合法的使用关键字strictfp 

Java代码  收藏代码
  1. strictfp interface A {}  
  2.   
  3. public strictfp class FpDemo1 {  
  4.     strictfp void f() {}  
  5. }  


2. 错误的使用方法 

Java代码  收藏代码
  1. interface A {  
  2.     strictfp void f();  
  3. }  
  4.   
  5. public class FpDemo2 {  
  6.     strictfp FpDemo2() {}  
  7. }  


一旦使用了关键字strictfp来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE-754规范的。例如一个类被声明为strictfp,那么该类中所有的方法都是strictfp的。 



Keys: volatile 

使用对象:字段 

介绍:因为异步线程可以访问字段,所以有些优化操作是一定不能作用在字段上的。volatile有时 

可以代替synchronized。 




Keys:transient 

  使用对象:字段 

  介绍:字段不是对象持久状态的一部分,不应该把字段和对象一起串起。


------------------------------------------------------------------------------------------------------------------------

transient 
  Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的

class A implements Serializable {
 private String name;
 transient private String address;
}

那么你在串行化(IO流等)A类时 给它的name和address属性赋值,那么你在提取A时,拿到了name属性,但是却拿不到address属性。


-------------------------------------------------------------------------------------------------------------


package text;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class ObjectIoTest {
		
	public static void main(String[] args) throws Exception {
		String fileName ="C:/Users/Administrator/Desktop/b.txt" ;
		Person p =new Person("shl", 27, new Date(1989, 1, 30));
		FileOutputStream out =new FileOutputStream(fileName);
		ObjectOutputStream output =new ObjectOutputStream(out);
		output.writeObject(p);
		System.out.println(p.getName()+"->"+p.getAge()+"->"+p.getBirthday());
		output.flush();
		output.close();
		out.close();
		
		FileInputStream in =new FileInputStream(fileName);
		ObjectInputStream input =new ObjectInputStream(in);
		p= (Person) input.readObject();
		System.out.println(p.getName()+"->"+p.getAge()+"->"+p.getBirthday());
		in.close();
		input.close();
		
		
	}
}




class Person implements Serializable {
	private String name;
	private transient int age;
	private Date birthday;

	Person() {

	}

	Person(String name, int age, Date birthday) {
		this.name = name;
		this.age = age;
		this.birthday = birthday;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}

将person对象保存到文件流中,再读取person的age设置 transient 属性。

测试的结果如下:

shl->27->Sat Mar 02 00:00:00 CST 3889
shl->0->Sat Mar 02 00:00:00 CST 3889

person对象初始age=27,写入文件中,再读取出来显示age=0,表明age的内容没有被保存~~




抱歉!评论已关闭.