java关键字

static关键字
静态的、全局的,一旦被static修饰说明在一定范围内是共享的,谁都可以访问,这时候就要注意并发读写问题
可以修饰变量、方法、方法块
1、修饰变量
如果是public的,任何类都可以调用,不用初始化类就可以调用。调用方法:类名.static变量。
此时要注意如果多个线程同时操作该数据,可能出现并发问题。
例如:public static List list = new ArrayList();
此时,当有多个线程同时访问该变量时,就会有线程安全问题。此时有两个解决方案:

(1)把线程不安全的ArrayList换成线程安全的CopyOnWriteArrayList;
(2)每次访问时,手动加锁;

所以,使用static修饰变量时,线程安全是我们必须要考虑的。

对于public static int num = 1;变量num自增时,num++,多线程下是不安全的,可以使用AtomicInteger类,保证原子性,线程安全;

AtomicInteger num = new AtomicInteger(1);//初始值为1
自增使用函数:num.incrementAndGet();

volatile特性:
1)保证变量在线程间可见,对volatile变量所有的写操作都能立即反应到其他线程中,换句话说,volatile变量在各个线程中是一致的(得益于java内存模型—“先行发生原则”);

2)禁止指令的重排序优;

使用volatile修饰变量,可以保证可见性,但是不能保证原子性。多个线程操作num++会有线程安全问题,所以对于该变量的操作必须加锁,保证同一时刻只有一个线程在操作该变量。

2、修饰方法
pubic static修饰方法可以被任意类直接调用,类名.方法名。不需要初始化类。此时,没有线程安全问题,因为方法是在栈里执行的,每个线程都有自己独立的栈,相互隔离,互不影响。util包里经常会用到static修饰方法,调用方便。
3、静态块
在类启动之前,初始化一些数据

public staic List<String> list = new ArrayList<String>();
static{
	list.add("abc");
}

静态块里的变量必须是静态的,而且需要写在静态块的前面,否则编译报错。
4、初始化时间

public class ParentStaticClass {
    public static List<String> list = new ArrayList<String>(){{
            System.out.println("父类静态变量初始化。。。");
    }};
    public ParentStaticClass(){
        System.out.println("父类构造函数初始化。。。");
    };
    static{
        System.out.println("父类静态块初始化。。。");
    }
    public static void test(){
        System.out.println("父类静态方法被执行。。。");
    }
}

public class StaticClass extends ParentStaticClass {
    public static List<String> list = new ArrayList<String>(){{
        System.out.println("子类静态变量初始化。。。");
    }};
    public StaticClass(){
        System.out.println("子类构造函数初始化。。。");
    }
    static {
        System.out.println("子类静态块初始化。。。");
    }
    public static void test(){
        System.out.println("子类静态方法执行。。。");
    }

    public static void main(String[] args){
        System.out.println("子类main方法执行。。。");
        new StaticClass();
    }
}
执行结果:
父类静态变量初始化。。。
父类静态块执行。。。
子类静态变量初始化。。。
子类静态块执行。。。
子类main方法执行。。。
父类构造函数初始化。。。
子类构造函数初始化。。。

结论:
(1)父类的静态变量和静态块比子类的先初始化;
(2)静态变量和静态块比构造函数先初始化;
静态方法在类初始化的时候并没有初始化,当被调用时才初始化。

final关键字
final的意思是不变的,通常有3中应用场景:
(1)修饰类,表示该类不能被继承;
(2)修饰方法,说明方法不能被覆写;
(3)修饰变量,说明变量只能初始化一次,初始化以后不能修改其内存地址。
对于第3中,只是不能修改内存地址,内部的值是可以改变的。
pubic static final List list = new ArrayList();
list可以先声明后初始化,修饰成员变量时,可以在构造函数中初始化,加上static也可以在静态块中初始化,修饰局部变量时,可以在具体的逻辑里初始化。

list.add("abc");

但是不能这样:

List<String> anotherList = new ArrayList<String>();
anotherList.add("abc");
list = anotherList;//这样list就指向了另外的内存地址。会报错。

try…catch…finally

 try{
     System.out.println("try is run...");
     while (true){
          throw new RuntimeException("try exception");
     }
     }catch (Exception e){
        System.out.println("catch is run...");
        throw new RuntimeException("catch exception");
     }finally {
        System.out.println("finally is run...");
     }
 运行结果:
 try is run...
 catch is run...
 finally is run...
 Exception in thread "main" java.lang.RuntimeException: catch exception

(1)finally执行后,才抛出catch的异常。
(2)最终捕获的异常是catch的异常,因为try的异常被catch吃掉了。这种情况可以打印下try的异常,这样在日志中就能看到try抛出的异常是什么了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值