一、注解

注解是JDK1.5之后提供一种新的注释方式,它的格式是:@Annotation
注解实际上就是注释的一种,但是它与注释稍微又有些区别
1、注解在一定程度上有 注释的作用
2、注解可以定义的属性,并且它的这些属性在Java代码依旧可以再次使用(反射)
3、注解可以和第3方类达成一定的约定(约定优于配置)

1.1 Java中常见的注解

@Override 重写注解
@Deprecated 废弃代码

  1. /**
  2. * 女孩抽象类
  3. * @author Administrator
  4. *
  5. */
  6. public abstract class Girl {
  7. public abstract void cry();
  8. }
    public interface Flyable {
        void fly();
    }
public class GentleGirl extends Girl implements Flyable{
    @Override
    public void cry() {
        // TODO Auto-generated method stub
    }
    @Deprecated
    @Override
    public void fly() {
        // TODO Auto-generated method stub
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString();
    }
}

1.2 自定义一个注解

由于Java的注解无法满足所有人的要求,所以需要自定义注解
定义在注解上方的注解:元注解
元注解
@Documented 文档注解 作用:允许注解可以导出成API
@Target 目标注解 作用:描述注解能够使用的位置
@Retention 注解生命周期,作用:描述注解在 源码,编译,运行期 这3个范围的生命周期
@Inherited 被它修饰的注解具有继承性,作用:如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解

    /**
     * 作用:该注解的作用是为了为学生讲解如何自定义注解
     *
     */
    @Documented
    @Target(value= {ElementType.TYPE,ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface InitAnnotation {
        String effect();
        /**
         * default 可以给注解 添加默认值
         * 添加默认值以后,该属性就不是一个必须属性    
         * @return
         */
        String remark() default "";
    }
    @InitAnnotation(effect="这是一个女孩类")
    public class GentleGirl extends Girl implements Flyable{
        @Override
        public void cry() {
            // TODO Auto-generated method stub
        }
        @Deprecated
        @Override
        public void fly() {
            // TODO Auto-generated method stub
        }
        @InitAnnotation(effect="重写了toString()方法",remark="asdf")
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return super.toString();
        }
    }

二、枚举

枚举是JDK1.5以后提供的一种新的引用类型
它是对接口中常量的一种特殊面向对象的写法

    public interface Colorable{
        public static final String RED = 0;
        public static final String GREEN = 1;
        public static final String BLACK = 2;
    }

平时使用的接口类,如果我们不知道其中0,1,2的含义,就很难判断条件,使用枚举可以解决该问题。
例如:

    public enum ColorType{
        RED(0,"红色"),GREEN(1,"绿色"),BLACK(2,"黑色");
        private int index;
        private String desc;
        private ColorType(int index,String desc){
            this.index = index;
            this.desc = desc;
        }
        …… getter() 以及setter()
    }

枚举定义时

1、枚举类的定义,和枚举对象的产生在同一个地方
2、枚举类不能通过new的方式来产生实例
3、枚举对象必须要放置在枚举类的首行
4、枚举可以构造器,但是构造器必须定义成私有的
枚举来源至:对接口常量数据的 对象化 封装

三、异常

异常就是指程序抛出的问题

3.1 问题分类

3.1.1 错误

Error 错误不能算为异常,因为它,程序员是没办法处理的。例如:内存不足,硬盘空间不够,网线被断了,服务器停电了……

3.1.2 异常

Exception 就程序员通过代码是可以解决的问题。

编译期异常

指在编写代码过程,由编译期主动识别出来的问题,就是编译期异常

运行时异常

指在编写代码过程中,编译期识别不出来,但是在运行期由JVM抛出来的问题

3.1.3 异常的解决方案

运行时异常解决方案

抛出来以后再解决

编译时异常解决方案

编译时异常有3种解决方案:
1、捕获这个异常,不让它沿着调用栈继续向下抛出

    private static void method02() {
        try {
            //编译时异常
            File file = new File("D://test.txt");
            FileInputStream in = new FileInputStream(file);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }

2、捕获这个异常,并继续向下抛出;

private static void method02() throws Exception{
        try {
            //编译时异常
            File file = new File("D://test.txt");
            FileInputStream in = new FileInputStream(file);
        }catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            throw e;
        }
    }

3、不捕获这个异常,从而导致method1()方法从调用栈中被弹出,异常对象继续抛给调用栈下面的main()方法。

        private static void method02() throws Exception{
                //编译时异常
            File file = new File("D://test.txt");
            FileInputStream in = new FileInputStream(file);
        }

3.2 识别异常

凡是直接继承Exceptioin类,或者是它子类的派生几乎都是编译时异常
凡是直接继承RuntimeException类, 或者是它子类的派生都是运行时异常

3.3 捕获异常

语法:

    try {
        //监控代码,抛不抛异常
    }catch(Exception e){
        //如何解决异常
    }

案例:

        private static void method02() {
            System.out.println("开始");
            // 编译时异常
            File file = new File("D://test.txt");
            try {
                FileInputStream in = new FileInputStream(file);
                //如果上述代码,抛出异常,下面的代码不会执行
                System.out.println("asdfasdfasdfasdasdf");
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("抛异常……");
            }
            System.out.println("结束");
        }

3.4 自定义编译时异常

/**
 * 自定义 编译期异常
 * @author ly
 *
 */
public class InitException extends Exception{
    public InitException() {
        super();
        // TODO Auto-generated constructor stub
    }
    public InitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
        // TODO Auto-generated constructor stub
    }
    public InitException(String message, Throwable cause) {
        super(message, cause);
        // TODO Auto-generated constructor stub
    }
    public InitException(String message) {
        super(message);
        // TODO Auto-generated constructor stub
    }
    public InitException(Throwable cause) {
        super(cause);
        // TODO Auto-generated constructor stub
    }

3.5 使用异常

        private static int add(int a,int b) throws InitException {
            if(a < 0 || b < 0) {
                throw new InitException("传入的参数为:负数");
            }
            return a + b;
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            try {
                add(4,5);
            } catch (InitException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

3.6 异常的多态性

当有多个异常同时抛出时,可以使用多个catch()进行捕获,但是务必记住一点:
catch()的顺序,一定要是从小到大,因为它有自动转向
catch()的执行顺序,是从上到下依次执行

    import java.util.Scanner;
    public class MainEnter {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入2个数:");
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            try {
                System.out.println(CalcUtil.add(a, b));
                System.out.println(CalcUtil.sub(a, b));
                System.out.println(CalcUtil.mul(a, b));
                System.out.println(CalcUtil.div(a, b));
            } catch (DivZeroException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("asdfasdf");
            } catch (InputIllegalException e) {
                // TODO: handle exception
                e.printStackTrace();
                System.out.println("123123123");
            }
            scanner.close();
        }
    }

3.7 finally

finally 表示必须执行的代码,通常和try-catch配合使用。它的执行顺序是在:程序抛出异常之前,或者程序执行return之前;但是return 放置在try之前,finally中的代码不会执行

    import java.util.Scanner;
    public class MainEnter {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入2个数:");
            int a = scanner.nextInt();
            int b = scanner.nextInt();
            try {
                System.out.println(CalcUtil.add(a, b));
                System.out.println(CalcUtil.sub(a, b));
                System.out.println(CalcUtil.mul(a, b));
                System.out.println(CalcUtil.div(a, b));
                System.out.println("我是return之前的代码!!!");
            } catch (DivZeroException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("asdfasdf");
            } catch (InputIllegalException e) {
                // TODO: handle exception
                e.printStackTrace();
                System.out.println("123123123");
            }finally {
                //必须需要执行的代码块
                //通常这块的内容:用来关闭流,关闭连接,清理垃圾,清理资源
                System.out.println("我是必须执行的代码!!!");
                scanner.close();
            }
        }
    }

3.8 自定义运行时异常

    /**
     * 数组下标越界|非法
     * 运行时异常
     * @author ly
     *
     */
    public class ArrayIndexIllegalException extends RuntimeException {
        public ArrayIndexIllegalException() {
            super();
            // TODO Auto-generated constructor stub
        }
        public ArrayIndexIllegalException(String message, Throwable cause, boolean enableSuppression,
                boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
            // TODO Auto-generated constructor stub
        }
        public ArrayIndexIllegalException(String message, Throwable cause) {
            super(message, cause);
            // TODO Auto-generated constructor stub
        }
        public ArrayIndexIllegalException(String message) {
            super(message);
            // TODO Auto-generated constructor stub
        }
        public ArrayIndexIllegalException(Throwable cause) {
            super(cause);
            // TODO Auto-generated constructor stub
        }
    }
    public class MainEnter {
        public static void main(String[] args) {
            int[] nums = {12,45,23,67,34,45};
            //运行时异常,解决方案:让它抛,抛完了,我们再解决
            if(5 < nums.length) {
                System.out.println(getElementByIndex(nums, 5));
            }
        }
        /**
         * 根据下标从数组中返回元素
         * 运行时异常,不需要进行方法异常申明
         * @param nums
         * @param index
         * @return
         */
        public static int getElementByIndex(int[] nums,int index) {
            int lenth = nums.length;
            if(index >= lenth || index < 0) {
                throw new ArrayIndexIllegalException("数组下标越界:" + index);
            }
            return nums[index];
        }
    }

3.9 重写与异常

子类的方法,不能抛出比父类更多,更大的异常