Java关键字之native,strictfp,transient,volatile (SCJP)

    技术2024-04-17  19

    Java关键字(keywords)

    abstract    default    if            private      this boolean     do         implements    protected    throw break       double     import        public       throws byte        else       instanceof    return       transient case        extends    int           short        try catch       final      interface     static       void char        finally    long          strictfp     volatile class       float      native        super        while const       for        new           switch continue    goto       package       synchronized

    以上是java specifications中定义的keywords,一共48个,其中常见的三个看似是关键字的true, false, null,都不是关键字,而是作为一个单独标识类型。 其中,不常用到的关键字有:const,goto,native,strictfp,transient,volatile。 constgoto 为java中的保留字。

    1. native native 是方法修饰符。Native方法是由另外一种语言(如c/c++,FORTRAN,汇编)实现的本地方法。因为在外部实现了方法,所以在java代码中, 就不需要声明了,有点类似于借口方法。Native可以和其他一些修饰符连用,但是abstract方法和Interface方法不能用native来修 饰。 Example:

    public interface TestInterface { void doMethod(); } public class Test implements TestInterface { public native void doMethod(); private native int doMethodB();   public native synchronized String doMethodC();   static native void doMethodD(); }

    为什么需要使用native method?请参考: http://www.javaeye.com/topic/72543   java Native Method初涉

     

    2. strictfp

     

    自Java2以来,Java语言增加了一个关键字 strictfp ,虽然这个关键字在大多数场合比较少用,但是还是有必要了解一下。      strictfp 的意思是FP-strict,也就是说精确浮点的意思。在Java虚拟机进行浮点运算时,如果没有指定 strictfp 关键字时,Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令你满意。而一旦使用了 strictfp 来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE- 754 来执行。因此如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字 strictfp 。      你可以将一个类、接口以及方法声明为strictfp ,但是不允许对接口中的方法以及构造函数声明 strictfp 关键字,例如下面的代码:      1 . 合法的使用关键字 strictfp       strictfp   interface  A {}      public   strictfp   class  FpDemo1 {       strictfp   void  f() {}   }      2 . 错误的使用方法      interface  A {       strictfp   void  f();   }      public   class  FpDemo2 {       strictfp  FpDemo2() {}   }      一旦使用了关键字strictfp 来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE- 754 规范的。例如一个类被声明为 strictfp ,那么该类中所有的方法都是 strictfp 的。  

    自 Java2以来,Java语言增加了一个关键字strictfp,虽然这个关键字在大多数场合比较少用,但是还是有必要了解一下。 strictfp的意思是FP-strict,也就是说精确浮点的意思。在Java虚拟机进行浮点运算时,如果没有指定strictfp关键字 时,Java的编译器以及运行环境在对浮点运算的表达式是采取一种近似于我行我素的行为来完成这些操作,以致于得到的结果往往无法令你满意。而一旦使用了 strictfp来声明一个类、接口或者方法时,那么所声明的范围内Java的编译器以及运行环境会完全依照浮点规范IEEE-754来执行。因此如果你 想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,那就请用关键字strictfp。 你可以将一个类、接口以及方法声明为strictfp,但是不允许对接口中的方法以及构造函数声明strictfp关键字,例如下面的代码: 1. 合法的使用关键字strictfp strictfp interface A {} public strictfp class FpDemo1 { strictfp void f() {} } 2. 错误的使用方法 interface A { strictfp void f(); } public class FpDemo2 { strictfp FpDemo2() {} } 一旦使用了关键字strictfp来声明某个类、接口或者方法时,那么在这个关键字所声明的范围内所有浮点运算都是精确的,符合IEEE-754规范的。 例如一个类被声明为strictfp,那么该类中所有的方法都是strictfp的。 修饰类和方法,意思是FP-strict,精确浮点,符合IEEE-754规范的。当一个class或interface 用strictfp声明,内部所有的float和double表达式都会成为strictfp的。Interface method不能被声明为strictfp的,class的可以。 Example:

    strictfp   interface  FPTest {        void  methodA();   }   class  FPClass  implements  FPTest {       public   void  methodA() {       }       public   void  methodB() {     }     public   strictfp   void  methodC() {     }   }   class  FPClassB {       strictfp   void  methodA() {       }   }  

    strictfp interface FPTest { void methodA(); } class FPClass implements FPTest { public void methodA() { } public void methodB() {   }   public strictfp void methodC() {   } } class FPClassB { strictfp void methodA() { } }

    3.transient 变量修饰符。标记为transient的变量,在对象存储时,这些变量状态不会被持久化。当对象序列化的保存在存储器上时,不希望有些字段数据被保存,为了保证安全性,可以把这些字段声明为transient。

    4. volatile volatile修饰变量。在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。 看看Java Language Specification中的例子。 条件:一个线程不停的调用方法one(),一个线程不停的调用方法two()。我测试过多次,这种情况好像一直没有出现。

    class  Test {       static   int  i =  0 , j =  0 ;       static   void  one() { i++; j++; }       static   void  two() {           System.out.println("i="  + i +  " j="  + j);       }   }  

    class Test { static int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } }

    结果偶尔会出现j大于i的情况,因为方法没有同步,所以会出现i和j可能不是一次更新。一种防止这种情况发生的办法就是声明两个方法为synchronized 的。 

    class  Test {       static   int  i =  0 , j =  0 ;       static   synchronized   void  one() { i++; j++; }       static   synchronized   void  two() {           System.out.println("i="  + i +  " j="  + j);       }   }  

    class Test { static int i = 0, j = 0; static synchronized void one() { i++; j++; } static synchronized void two() { System.out.println("i=" + i + " j=" + j); } }

    这样可以防止两个方法同时被执行,还可以保证j和i被同时更新,这样一来i和j的值一直是一样的。 另外一种途径就是把i和j声明为volatile。

    class  Test {       static   volatile   int  i =  0 , j =  0 ;       static   void  one() { i++; j++; }       static   void  two() {           System.out.println("i="  + i +  " j="  + j);       }   }  

    class Test { static volatile int i = 0, j = 0; static void one() { i++; j++; } static void two() { System.out.println("i=" + i + " j=" + j); } }

    转自:http://www.javaeye.com/topic/82640

    最新回复(0)