1. static
/**
* Created by fun on 2017/2/13.
*/
public class StaticDemo {
private static String prop = null;
static{
prop = "static";
System.out.println("static code block.......");
}
public StaticDemo(){
prop = "constructor";
System.out.println("constructor.......");
}
public static void sayHello(){
System.out.println("sayHello method print the prop="+prop);
}
public void sayHello2(){
prop = "sayHello2";
System.out.println("sayHello2 method print the prop="+prop);
}
}
- 使用StaticDemo的任何方法(静态或者非静态方法),static代码块仅且执行一次
- 非静态成员方法可以操作静态成员变量的值
- 构造方法只在new 关键字出现,new新的对象的时候调用,使用类名直接调用静态方法的时候没有调用构造方法
- static不能用来修饰普通内部类中的变量,如果内部类本身是static的是可以的
2. final
在java中,可能使用到final关键字修饰的有数据、方法和类。
2.1 final 修饰数据
有final修饰的数据是用来告诉编译器一块数据是恒定不变的,有时数据恒定不变是很有用的,比如:
- 一个永不改变的编译时常量。
- 一个在运行时被初始化的值,但是又不希望它被改变。
编译时常量必须是基本数据类型,并且以关键字final修饰,在对这个常量进行定义的时候必须进行赋值,并且以后不能被改变。
对于基本类型,final使数值恒定不变;而对于对象引用,final使引用恒定不变,也就是说某个引用不能再指向其他对象了,但是当前指向的这个对象自身的数据是可以改变的。
如何理解上面的解释呢,看如下示例:
public void test(final Student student) {
// student = new Student() // 这种写法就会报错,因为改变了student的指向,但是student是个final的。
student.setName("123"); // 这种操作是可以的,并且student的name会被成功修改
}
2.2 final修饰方法
使用final修饰方法的作用是把方法锁定,以防止任何继承类修改它的含义。在继承类中,使用了与父类用final修饰的方法同名的方法时,并没有覆盖父类的该方法,而是生成了一个新的方法。也就是说final修饰的方法不能被重写。
2.3 final修饰类
当将某个类定义为final时,就表明了你不打算继承该类,也不允许别人继承。
3. transient
使用transient 关键字,标记变量不被序列化和反序列化
谈到序列化,static 变量也是不会被序列化的
4. volatile
volatile 可以保证变量对所有线程的可见性,但是不能说是完全的线程,例如++ 操作是个非原子操作,就有可能出现问题
volatile只保证了可见性,在不满足以下情况的时候,需要加锁(synchronized 或者 java.util.concurrent中的原子类)来保证原子性
- 运算结果并不依赖变量的当前值,后者能够确保只有单一线程修改变量的值
- 变量不需要同其他的状态变量一起参与不变约束
volatile 修饰long / double 在多线程的时候可以把他们的读写变成原子的操作(现代的虚拟机已经把64位数据读写作为原子操作了)
volatile可以防止指令重排序
网友评论