一、注解
注解是JDK1.5之后提供一种新的注释方式,它的格式是:@Annotation
注解实际上就是注释的一种,但是它与注释稍微又有些区别
1、注解在一定程度上有 注释的作用
2、注解可以定义的属性,并且它的这些属性在Java代码依旧可以再次使用(反射)
3、注解可以和第3方类达成一定的约定(约定优于配置)
1.1 Java中常见的注解
@Override 重写注解
@Deprecated 废弃代码
/**
* 女孩抽象类
* @author Administrator
*
*/
public abstract class Girl {
public abstract void cry();
}
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 异常
编译期异常
指在编写代码过程,由编译期主动识别出来的问题,就是编译期异常
运行时异常
指在编写代码过程中,编译期识别不出来,但是在运行期由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 重写与异常
子类的方法,不能抛出比父类更多,更大的异常