文章目录
- 前言
- 一、自定义枚举类
- 二、enum定义枚举类
- 1.常用的方法
- 2.枚举类实现接口
- 三、注解
- 1、JDK内置的基本注解类型
- 2、自定义注解
- 3、元注解
- 4、解析注解
- 5、注解练习
前言
JDK1.5之前需要自定义枚举类
JDK1.5新增的enum关键字用于定义枚举类
若枚举只有一个成员,则可以作为一种单例模式的实现方式
一、自定义枚举类
package com.enums;
/**
* 季节测试枚举
*/
public class TestSeason {
public static void main(String[] args) {
Season spring = Season.SPRING;
System.out.println(spring);
System.out.println(spring.getSeasonName());
}
}
/**
* 枚举类
*/
class Season {
//1.提供类的属性,声明为private final
private final String seasonName;
private final String seasonDesc;
//2.声明final的属性,在构造器中初始化
private Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
//3.通过公共的方法的来调用属性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
//4.创建枚举类的对象
public static final Season SPRING = new Season("spring", "春天");
public static final Season SUMMER = new Season("summer", "夏天");
public static final Season AUTUMN = new Season("autumn", "秋天");
public static final Season WINTER = new Season("winter", "冬天");
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
二、enum定义枚举类
1.常用的方法
package com.enums;
/**
* 季节测试枚举
*/
public class TestSeason2 {
public static void main(String[] args) {
SeasonEnum spring = SeasonEnum.SPRING;
System.out.println(spring);
System.out.println(spring.getSeasonName());
//1.values
SeasonEnum[] seasonEnums = SeasonEnum.values();
for (SeasonEnum season : seasonEnums) {
System.out.println(season);
}
//2.valueOf
String str = "SPRING";
SeasonEnum seasonEnum2 = SeasonEnum.valueOf(str);
System.out.println(seasonEnum2);
}
}
/**
* enum枚举类
*/
enum SeasonEnum {
SPRING("spring", "春天"),
SUMMER("summer", "夏天"),
AUTUMN("autumn", "秋天"),
WINTER("winter", "冬天");
private final String seasonName;
private final String seasonDesc;
private SeasonEnum(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
2.枚举类实现接口
可以让不同的枚举类对象(SPRING、SUMMER 就是实例化的对象public static final Season SPRING = new Season("spring", "春天"); )调用被重写的抽象方法,执行的重新的方法效果不同。
package com.enums;
/**
* 季节测试枚举
*/
public class TestSeason2 {
public static void main(String[] args) {
SeasonEnum spring = SeasonEnum.SPRING;
System.out.println(spring);
System.out.println(spring.getSeasonName());
//1.values
SeasonEnum[] seasonEnums = SeasonEnum.values();
for (SeasonEnum season : seasonEnums) {
System.out.println(season);
}
//2.valueOf
String str = "SPRING";
SeasonEnum seasonEnum2 = SeasonEnum.valueOf(str);
System.out.println(seasonEnum2);
//3.枚举类实现接口
spring.show();
}
}
interface Info {
void show();
}
/**
* enum枚举类
*/
enum SeasonEnum implements Info {
/**
* SPRING、SUMMER、AUTUMN、WINTER都重写了接口的show()方法
*/
SPRING("spring", "春天") {
public void show() {
System.out.println("春天来了");
}
},
SUMMER("summer", "夏天") {
public void show() {
System.out.println("夏天来了");
}
},
AUTUMN("autumn", "秋天") {
public void show() {
System.out.println("秋天来了");
}
},
WINTER("winter", "冬天") {
public void show() {
System.out.println("冬天来了");
}
};
private final String seasonName;
private final String seasonDesc;
private SeasonEnum(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
// @Override
// public void show() {
// System.out.println("枚举类实现接口");
// }
}
三、注解
注解:注解是对代码的一种增强,可以在程序运行或者编译期间获取注解的信息,然后根据这些注解信息做各种事情,比如重写父类的方法等。
从JDK1.5开始,Java增加了对元数据的支持,也就是annotation注解
1、JDK内置的基本注解类型
@Override重写父类方法
@Deprecated表示某个程序的类方法已过时
@SuppressWarnings抑制警告
2、自定义注解
1.注解的语法
public @interface MyAnnotation {
}
2.注解中定义参数
public @interface 注解名称{
[public] 参数类型 参数名称1()[default 参数默认值];
[public] 参数类型 参数名称2()[default 参数默认值];
}
注解中可以定义多个参数,参数的定义有以下特点:
1)访问修饰符必须为public,不写默认为public
2)该元素的类型只能是基本数据类型、String、Class、枚举类型、注解类型(体现了注解的嵌套效果)以及上述类型的一位数组
3)该元素的名称一般定义为名词,如果注解中只有一个元素,请把名字起为value(后面使用会带来便利操作)
4)参数名称后面的()不是定义方法参数的地方,也不能在括号中定义任何参数,仅仅只是一个特殊的语法
5)default代表默认值,值必须和第2点定义的类型一致
6)如果没有默认值,代表后续使用注解时必须给该类型元素赋值
7)成员无参无异常方式声明
3.使用范围
@Target
package java.lang.annotation;
/*注解的使用范围*/
public enum ElementType {
/*类、接口、枚举、注解上面*/
TYPE,
/*字段上*/
FIELD,
/*方法上*/
METHOD,
/*方法的参数上*/
PARAMETER,
/*构造函数上*/
CONSTRUCTOR,
/*本地变量上*/
LOCAL_VARIABLE,
/*注解上*/
ANNOTATION_TYPE,
/*包上*/
PACKAGE,
/*类型参数上*/
TYPE_PARAMETER,
/*类型名称上*/
TYPE_USE
}
3、元注解
元注解就是给注解进行注解
@Target 使用范围
@Retention:用指定注解可以保留多长时间(@Retention有一个value参数,类型为RetentionPolicy枚举)
public enum RetentionPolicy {
/*注解只保留在源码中,编译为字节码之后就丢失了,也就是class文件中就不存在了*/
SOURCE,
/*注解只保留在源码和字节码中,运行阶段会丢失*/
CLASS,
/*源码、字节码、运行期间都存在*/
RUNTIME
}
@Inherited
作用:让子类可以继承父类中被@Inherited修饰的注解,注意是继承父类中的,如果接口中的注解也使用@Inherited修饰了,那么接口的实现类是无法继承这个注解的。只会继承类上的注解
@Documented 生成Javadoc时会包含注解
4、解析注解
方式一:
public static void main(String[] args) {
try {
//1.使用类加载器加载类
Class c = Class.forName("com.annotations.Person");
//2.找到类上面的注解,判断这个注解是否存在
boolean isExist = c.isAnnotationPresent(MyAnnotation.class);
if (isExist) {
//3.拿到注解的实例
MyAnnotation myAnnotation = (MyAnnotation) c.getAnnotation(MyAnnotation.class);
System.out.println("获取类上面的注解:"+myAnnotation.value());
}
//4.找到方法上的注解
Method[] methods = c.getMethods();
for (Method m :methods){
boolean isMExist = m.isAnnotationPresent(MyAnnotation.class);
if(isMExist){
MyAnnotation myMethod = m.getAnnotation(MyAnnotation.class);
System.out.println("获取方法上面的注解:"+myMethod.value());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
方式二:
public static void main(String[] args) {
try {
//1.使用类加载器加载类
Class c = Class.forName("com.annotations.Person");
//2.找到类上面的注解,判断注解是否存在
boolean exist = c.isAnnotationPresent(MyAnnotation.class);
if (exist) {
//3.获取注解的实例
MyAnnotation myAnnotation = (MyAnnotation) c.getAnnotation(MyAnnotation.class);
System.out.println("获取类上面的注解:" + myAnnotation.value());
//4.找到方法上面的注解
Method[] methods = c.getMethods();
for (Method m : methods) {
//5.获取所有的注解
Annotation[] myAnnotation1 = m.getAnnotations();
for (Annotation my : myAnnotation1){
if(my instanceof MyAnnotation){
MyAnnotation mn = (MyAnnotation) my;
System.out.println("获取方法上面的注解:"+mn.value());
}
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
5、注解练习
注解类
package com.annotations;
/**
* 注解类
*/
@Table("job")
public class Filter {
@Column("id")
private String id;
@Column("phone")
private String phone;
@Column("email")
private String email;
@Column("address")
private String address;
@Column("job_name")
private String jobName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getJobName() {
return jobName;
}
public void setJobName(String jobName) {
this.jobName = jobName;
}
@Override
public String toString() {
return "Filter{" +
"id='" + id + '\'' +
", phone='" + phone + '\'' +
", email='" + email + '\'' +
", address='" + address + '\'' +
", jobName='" + jobName + '\'' +
'}';
}
}
表名注解
package com.annotations;
import java.lang.annotation.*;
/**
* 用于注解表名
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
String value();
}
字段的注解
package com.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于注解字段
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
String value();
}
测试类
package com.annotations;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 测试注解的表
*/
public class TableAnnotationTest {
public static void main(String[] args) {
Filter f1 = new Filter();
f1.setId("10");//查询id为10的用户
Filter f2 = new Filter();
f2.setJobName("lucy");//查询名为lucy用户
f2.setAddress("陆家嘴");
Filter f3 = new Filter();
f3.setEmail("li@qq.com,ming@163.com,yuan@sina.com");
String sql1 = query(f1);
String sql2 = query(f2);
String sql3 = query(f3);
System.out.println(sql1);
System.out.println(sql2);
System.out.println(sql3);
}
/**
* 查询sql
*
* @param f
* @return
*/
private static String query(Object f) {
//1.获取加载的类
Class c = f.getClass();
//2.获取表名,并判断是否存在
boolean tableExist = c.isAnnotationPresent(Table.class);
if (!tableExist) {
return null;
}
//3.获取表名注解的实例对象
Table table = (Table) c.getAnnotation(Table.class);
//4.获取表名
String tableName = table.value();
//5.存放拼装sql
StringBuffer sb = new StringBuffer();
sb.append("select * from ").append(tableName).append(" where 1 = 1 ");
//6.利用反射获取所有的字段
Field[] files = c.getDeclaredFields();
for (Field field : files) {
//7.获取注解的字段实例,并判断是否存在
boolean columnExist = field.isAnnotationPresent(Column.class);
if (!columnExist) {
continue;
}
Column column = (Column) field.getAnnotation(Column.class);
//8.获取所有注解上的字段值
String columnValue = column.value();
//9.利用反射获取所有字段名称
String fieldName = field.getName();
//10.获取方法名..利用getName
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Object fieldValue = null;
try {
//11.获取所有的方法
Method methods = c.getMethod(getMethodName);
//12.通过反射调用,传入对象和参数
fieldValue = methods.invoke(f);
//拼装sql
if (fieldValue == null ||
(fieldValue instanceof Integer && (Integer) fieldValue == 0)) {
continue;
}
sb.append(" and ").append(columnValue);
//如果拼接的sql的字段的是模糊查询加%
if (fieldValue instanceof String) {
if (((String) fieldValue).contains(",")) {
String[] array = ((String) fieldValue).split(",");
sb.append(" in(");
for (String em : array) {
sb.append("'").append(em).append("'").append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
} else {
sb.append(" = ").append("'" + fieldValue + "'");
}
} else if (fieldValue instanceof Integer) {
sb.append(" = ").append(fieldValue);
} else {
sb.append(" = ").append(fieldValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return sb.toString();
}
}