1、注解
/**
* 注解 : 是一种特殊的注释, 特殊在于可以被编译器, VM识别. 本质上是一个修饰符, 注解都不能修饰语句.
* @Override 作用是提醒编译器, 它修饰的方法是一个覆盖方法, 请帮助我们作检查 , 方法覆盖条件的检查.
* 只可以修饰方法.
*
* @Deprecated 作用是提醒编译器,提醒使用者 它修饰的目标不推荐使用
* 它可以
* 修饰类(TYPE), 属性(FIELD), 构造器(CONSTRUCTOR), 方法(METHOD),
* 局部变量(LOCAL_VARIABLE), 参数(PARAMETER)
*
* @SuppressWarnings 抑制编译器警告, 在使用时必须传参, 说明它内部有属性.
*
* 元注解 : 注解的注解, 约束注解的使用的注解.
* @Target 作用是约束注解可以修饰的目标.可以用在什么位置, 默认情况是它可以修饰任意目标
* ElementType.TYPE 类型(类类型,接口类型)
* ElementType.FIELD 属性
* ElementType.METHOD 方法
* ElementType.CONSTRUCTOR 构造器
* ElementType.PARAMETER 参数
*
* @Retention 作用是约束注解可以停留在什么时期, 是只在源文件中呢, 还是在类文件中, 还是都在且运行时能获取.
*/
// 自定义注解, 可以修饰任意目标. 这是一个标记型注解
//@interface MyAnnotation {}
// 自定义注解, 可以修饰任意目标. 这是一个有参数的注解, 默认可以修饰任意目标
/*
@interface MyAnnotation {
int id() default 200; // 属性可以有缺省值.
String name() default "缺省值";
}*/
/*
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) // 自定义注解只可以修饰类和属性. 其他都不行了.默认情况下此注解停留在类文件中
@interface MyAnnotation {
int id() default 200;
String name() default "缺省值";
}
*/
代码演示
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER}) // 自定义注解只可以修饰类和属性. 其他都不行了.
@Retention(RetentionPolicy.RUNTIME) // MyAnnotation注解就可以在运行时通过反射获取并处理了..
@interface MyAnnotation {
int id() default 200;
String name() default "缺省值";
}
//@Override
@Deprecated
@MyAnnotation(id = 1, name="abc")
class Person {
//@Override
private String name;
@Deprecated
@MyAnnotation(name="yyy", id = 2) private int age;
private String gender;
@Deprecated
/*@MyAnnotation(name="zzz")*/ public Person() {
}
//@Override
// <init>()
public Person(@Deprecated String name, int age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
@Deprecated
@SuppressWarnings({"unused", "null"})
/*@MyAnnotation(name="zzz")*/ public String getName() {
@Deprecated int n;
double d;
//System.out.println(n);
/*@MyAnnotation*/ int[] arr = null;
System.out.println(arr.length);
return name;
}
/*@MyAnnotation*/ public void setName(@MyAnnotation String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override /*@MyAnnotation*/ public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
2、枚举
/**
* 枚举 : 对象可数的类型, 不能再创建新对象.
*/
代码演示
enum Season { // public static final 修饰的量. 称为全局常量
// 给Week枚举加上属性, String feel. 添加构造器. 改造toString().
SPRING("绿色"), SUMMER("红色"), AUTUMN, WINTER;
{
color = "白色"; // 非静态语句块和显式赋值的顺序是按照写的顺序来执行的 并且它们都是先于构造器
}
private String color = "黑色";
private Season() {}
private Season(String color) { // 构造器必须是私有的
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return super.toString() + " Season{" +
"color='" + color + '\'' +
'}';
}
}
public class EnumTest {
public static void main(String... args) {
int n = Integer.parseInt(args[0]); // 把命令行参数的第一个字符串转换成真的整数.
//new Season();
Season s1 = Season.SPRING; // 直接通过类.常量对象, 最直接的方式
System.out.println(s1); // s1.toString();
s1 = Season.valueOf("AUTUMN"); // 根据枚举对象名获取枚举对象, 大小写敏感
System.out.println(s1);
Season[] values = Season.values(); // 获取保存所有枚举对象的对象数组.
s1 = values[n];
System.out.println("****************************");
System.out.println(s1);
// s1中指向的对象是谁不确定... 枚举 : 可以列举, 穷举
switch (s1) { // switch(变量) 变量的类型:非long整数, 字符串, 枚举
case SPRING: // 常量 : 字面量, 被final修饰的量
System.out.println("春季");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}
代码演示
enum Week {
MON, TUE, WED, THU, FRI, SAT, SUN
}
//声明Week枚举类,其中包含星期一至星期日的定义;
// 在main方法中从命令行接收一个1-7的整数(使用Integer.parseInt方法转换),
// 分别代表星期一至星期日,打印该值对应的枚举值,
public class EnumExer {
/*
在TestWeek类中声明方法void printWeek(Week week),根据参数值打印相应的中文星期字符串。
然后以第2步中的枚举值调用printWeek方法,输出中文星期。*/
public void printWeek(Week week) {
switch (week) {
case MON:
System.out.println("星期一");
break;
case TUE:
System.out.println("星期二");
break;
case WED:
System.out.println("星期三");
break;
case THU:
System.out.println("星期四");
break;
case FRI:
System.out.println("星期五");
break;
case SAT:
System.out.println("星期六");
break;
case SUN:
System.out.println("星期日");
break;
}
}
public static void main(String[] args) {
int i = Integer.parseInt(args[0]);
if (i > 7 || i < 1) {
System.out.println("输入的参数不合法, 请输入[1~7]");
return;
}
Week[] values = Week.values();
Week value = values[i - 1];
System.out.println(value);
EnumExer exer = new EnumExer();
exer.printWeek(value); // 非静态方法 它必须依赖对象!!!!!
}
}
3、异常
/**
* 异常 : 程序在运行时出现的非正常状况, 如果不处理会导致程序崩溃.
*
* 异常分类 :
* 1) 按照程度来分 :
* 1) Error 严重错误
* 2) Exception 一般问题
* 2) 按照处理方式来分 :
* 1) 受检异常(checked) 编译时异常 : 在程序中必须接受检查和处理的异常
* Exception及其子类, RuntimeException及其子类除外.
*
* 2) 非受检异常(unchecked) 运行时异常 : 在程序中不是必须接受检查和处理的异常.
* Error及其子类 太严重了
* RuntimeException及其子类 太轻微太常见
*
* 无论是受检异常还是非受检异常都会导致程序崩溃.
*
* 异常必须处理 : 异常的处理方式适用于所有异常, 包括Error
* 1) 捕获
* try {
* 可能抛出异常的语句;
* } catch (可能的异常类型1 引用) {
* 对异常对象1进行处理. 引用就指向了异常对象.
* }
* 2)
* 3)
*
*/
代码演示
public static void main(String[] args) {
System.out.println("main begin");
try {
int n1 = Integer.parseInt(args[0]); // 如果此语句出现异常, 整个try废掉.
// 如果命令行参数未传入任何内容, 会出现ArrayIndexOutOfBoundsException
// 如果命令行参数的内容是无法转换成整数的字符串, 会出现NumberFormatException
//int n2 = Integer.parseInt(args[1]);
System.out.println(n1);
int[] arr = null;
System.out.println(arr.length);
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace(); // 打印栈踪迹
} catch (NumberFormatException e) {
System.out.println(e.getMessage()); // 获取异常对象的消息
} catch (Exception e) { // 捕获任何可能的其他的异常
System.out.println("其他异常 : " + e);
}
// 被保护的语句
System.out.println("main end"); // 这是核心代码...
}
}
4、代理模式
/**
* 代理 : 把代理对象当成被代理对象来使用.
* 场景 :
* 1 使用者无法直接创建被代理对象
* 2 对于被代理对象的方法有改进的需求.但是同时不能修改被代理类.
*/
代码演示
interface HouseRent {
void rent();
}
class FangDong implements HouseRent {
@Override
public void rent() {
System.out.println("我有房子要出租, 刚结婚用的, 请爱护.... 账号1234567");
}
}
class FangDong2 implements HouseRent {
@Override
public void rent() {
System.out.println("我有房子要出租, 刚死了2个人, 不用开空调...");
}
}
class LianJia implements HouseRent {
private HouseRent hr = new FangDong2();
@Override
public void rent() {
System.out.println("请交中介费5000");
hr.rent(); // 原始方法调用, 这里是切面, 体现AOP
System.out.println("及时交房租, 不然赶走... 支持微信, 支付宝");
}
}
public class ProxyTest {
public static void main(String[] args) {
// 用户 : 只能new代理对象
HouseRent hr = new LianJia();
hr.rent();
}
}