Java编程杂记二

Java 空接口

空接口是没有包含任何方法的接口。叫标记接口。

标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其它代码来测试允许做一些事情。

标记接口作用:简单形象的说就是给某个对象打个标(盖个戳),使对象拥有某个或某些特权。

没有任何方法的接口被称为标记接口。标记接口主要用于以下两种目的

  1. 建立一个公共的父接口:

正如EventListener接口,这是由几十个其它接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。

例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

  1. 向一个类添加数据类型:

这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),实际上就是为了实现多态性。

我自己在实际项目也用到过标记接口,我在项目中负责ES的入库接口的开发,为了防止,其他开发人员随意调用接口往ES入数据,我在接口的入参定义了一个泛型

public void bulk(Class<? extends IndexModel> indexmodel)

这里的IndexModel就是一个标记接口,没有任何方法和属性,在一定程度减少了异常。

jdk中的空接口有:

import java.io.Serializable;//在ArrayList继承
import java.lang.annotation.Annotation;
import java.rmi.Remote;
import java.util.RandomAccess; //在ArrayList继承

Java断言关键字assert

java断言关键字assert需要在vm添加-ea参数。

  1. assert condition;

这里condition是一个必为真(true)的表达式。如表达式的结果为true,那断言为真,并且无任何行动
如果表达式为false,则断言失败,则会抛出一个AssertionError对象。这个AssertionError继承于Error对象,
而Error继承于Throwable,Error是和Exception并列的一个错误对象,通常用于表达系统级运行错误。
2. asser condition:expr;

这里condition是和上面样的这个冒号后跟的是个表达式,常用于断言败后的提示信息,白了它是一个
传到AssertionError构造函数的值,如果断言失败,该值被转化为它对应的字符串,并显示出来。

当执行代码时,使用-ea选项使断言有效,也可以使用-da选项使断言无效(默认为无效)
同样,也可以通过在-ea-da后面指定包名来使一个包的断言有效或无效。例如,要使一个com.test包中的断言
无效,可以使用:

-da:com.test

要使一个包中的所有子包中的断言能够有效或无效,在包名后加上三个点。例如:

-ea:com.test...

即可使com.test包及其子包中的断言无效。

Java多态

多态是同一个行为具有多个不同表现形式或形态的能力。

多态就是同一个接口,使用不同的实例而执行不同操作

多态的优点

  • 消除类型之间的耦合关系
  • 可替换性
  • 可扩充性
  • 接口性
  • 灵活性
  • 简化性

多态存在的三个必要条件

  • 继承
  • 重写
  • 父类引用指向子类对象

线程停止

情景模拟

假设现在又一个业务场景:这个业务场景的计算量非常大,非常耗时,为了不影响主线程的业务流程,需要启动一个新的线程去执行的,同时如果发现这个线程运行时间超过我们的预期时间限制(比如8小时)还没有运行完,就需要停止这个线程。防止系统内线程数量越来越多,最终导致OOM。

解决方案

方案一:stop()方法

public static void main(String[] args) {
    test();
}

public static void test(){
    Runnable thread = new Runnable() {
        @Override
        public void run() {
            Integer num = new Integer(0);
            System.out.println("thread is start");
            for (int i = 0; i < 1000000000; i++) {
                num++;
                //do something
            }
            System.out.println("thread has end");
        }
    };
    Thread thread1 = new Thread(thread);
    thread1.start();
    System.out.println("start");
    try {
        Thread.sleep(1000);
    }catch (InterruptedException ignore){}
    thread1.stop();
    System.out.println("end");
}

这种方法也是可行,但是JAVA手册不推荐使用stop方法。

方案二:interrupt()方法

public static void main(String[] args) {
    test();
}

public static void test(){
    Runnable thread = new Runnable() {
        @Override
        public void run() {
            Integer num = new Integer(0);
            System.out.println("thread is start");
            for (int i = 0; i < 1000000000; i++) {
                num++;
                //do something
                if (Thread.interrupted()){
                    break;
                }
                /**
                * 也可写成
                * if (Thread.currentThread().isInterrupted()){
                *    break;
                * }
                */
            }
            System.out.println("thread has end");
        }
    };
    Thread thread1 = new Thread(thread);
    thread1.start();
    System.out.println("start");
    try {
        Thread.sleep(1000);
    }catch (InterruptedException ignore){}
    thread1.interrupt();
    System.out.println("end");
}

Thread.sleep()为什么需要抛InterruptedException

当一个线程处于等待,睡眠,或者占用,也就是说阻塞状态,而这时线程被中断就会抛出这类错误。

Java6之后结束某个线程A的方法是A.interrupt()。如果这个线程正处于非阻塞状态,比如说线程正在执行某些代码的时候,不过被interrupt,那么该线程的interrupt变量会被置为true,告诉别人说这个线程被中断了(只是一个标志位,这个变量本身并不影响线程的中断与否),而且线程会被中断,这时不会有interruptedException。但如果这时线程被阻塞了,比如说正在睡眠,那么就会抛出这个错误。请注意,这个时候变量interrupt没有被置为true,而且也没有人来中断这个线程。

假设我们要结束一个线程。java6以后不推荐使用stop方法,而是interrupt方法,但是我们调用interrupt方法时不知道现成的状态是等待,睡眠,或者占用,当处于这几种状态之一时,我们调用interrupt中断线程。就会报异常。

public static void main(String[] args) {
    test();
}

public static void test(){
    Runnable thread = new Runnable() {
        @Override
        public void run() {
            Integer num = new Integer(0);
            System.out.println("thread is start");
            //do something

            try {
                Thread.sleep(100000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("thread has end");
        }
    };
    Thread thread1 = new Thread(thread);
    thread1.start();
    System.out.println("start");
    try {
        Thread.sleep(1000);
    }catch (InterruptedException ignore){}
    thread1.interrupt();
    System.out.println("end");
}

多个finally和return的执行顺序

finally不一定执行

  • 在System.exit(0)之后的finally不执行
private static void testfinaly(){
        int i = 0;
        try{

            try {

                try {

                }finally {
                    i = 4;
                    System.out.println(i);
                }
                i = 6;
                System.out.println(i);
                throw new RuntimeException();
            }catch (Exception e){

            }finally {
                i = 2;
                System.out.println(i);
            }
            i = 7;
            System.out.println(i);
            System.exit(0);
        }finally {
            i = 1;
            System.out.println(i);
        }
        i = 5;
        System.out.println(i);
    }

结果

4
6
2
7
  • 其他线程干扰,如stop

多个finally执行顺序

没有return的情况

private static void test(){
        int i = 0;
        try {

            try {
                try{
                    try{
                        i = 100;
                    }catch(Exception e){

                    }finally{
                        i = 1;
                        System.out.println(i);
                    }
                    i = 6;
                    System.out.println(i);
                }finally{
                    i = 2;
                    System.out.println(i);
                }
                i = 7;
                System.out.println(i);
                try{
                    Thread.sleep(10);
                }catch(Exception e){

                }finally{
                    i = 8;
                    System.out.println(i);
                }
            }finally {
                i = 3;
                System.out.println(i);
            }
        }finally {
            i = 4;
            System.out.println(i);
        }
        i = 5;
        System.out.println(i);
    }

结果

1
6
2
7
8
3
4
5

finally依次执行

有return的情况

private static int testfinaly(){
        int i = 0;
        try {

            try {
                try{
                    try{
                        i = 100;
                        System.out.println(i);
                        return i;
                    }catch(Exception e){

                    }finally{
                        i = 1;
                        System.out.println(i);
                    }
                    i = 6;
                    System.out.println(i);
                }finally{
                    i = 2;
                    System.out.println(i);
                }
                i = 7;
                System.out.println(i);
                try{
                    Thread.sleep(10);
                }catch(Exception e){

                }finally{
                    i = 8;
                    System.out.println(i);
                }
            }finally {
                i = 3;
                System.out.println(i);
            }
        }finally {
            i = 4;
            System.out.println(i);
        }
        i = 5;
        System.out.println(i);
        return i;
    }

结果

100
1
2
3
4
返回:100
private static int testfinaly(){
        int i = 0;
        try {

            try {
                try{
                    try{
                        i = 100;
                        System.out.println(i);

                    }catch(Exception e){

                    }finally{
                        i = 1;
                        System.out.println(i);
                    }
                    i = 6;
                    System.out.println(i);
                }finally{
                    i = 2;
                    System.out.println(i);
                }

                i = 7;
                System.out.println(i);
                try{
                    Thread.sleep(10);
                }catch(Exception e){

                }finally{
                    i = 8;
                    System.out.println(i);
                }
                return i;
            }finally {
                i = 3;
                System.out.println(i);
            }
        }finally {
            i = 4;
            System.out.println(i);
        }
    }

结果

100
1
6
2
7
8
3
4
返回:8

return之前的finally在return之前运行,在return之后的finally在之后return之后执行。

20200624补充

public class Main {
    private static int  testA(){
        int a = 9;
        a = a +9;
        a = a - 9;
        a = a+19;
        return a;
    }

    private static int  testB(){
        int a = 9;
        a = a +9;
        a = a - 9;
        a = a+19;
        return a;
    }
    private static int test(){
        try{
            return testA();
        }finally {
            testB();
        }
    }
    public static void main(String[] args) {
        test();
    }
}

这段代码先执行testA() 还是testB() ?

答案是testA()

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值