单例模式 单例 单个实例 某种类型只能有单个对象
1.枚举类型
-
此种类型的对象 指定个数个 对象;对象是固定的 固定就那么几个 对象都是提前定义好的;季节类型 春夏秋冬 时间单位类型 省份类型 颜色类型;
-
Java 枚举是一个特殊的类型,一般表示一组常量(一批对象 固定好的对象称之为一组常量),比如一年的 4 个季节,一个年的 12 个月份,一个星期的 7 天,方向有东南西北等。
-
枚举类型,本质就是个class 而且是一个是继承了Enum类的类型
-
对象都是提前定义好的 固定死的;实例和实例之间使用逗号隔开 最后一个实例使用分号;只需要写对象(实例)名称;常量名称一般都是大写;对象的声明必须在首行;
-
枚举类型的构造器默认全部都是私有化的 而且必须是private修饰
//枚举类型,本质就是个class 而且是一个是继承了Enum类的类型
public enum JiJie {
//对象都是提前定义好的 固定死的;实例和实例之间使用逗号隔开 最后一个实例使用分号;
//只需要写对象(实例)名称;常量名称一般都是大写
// 对象的声明必须在首行
// CHUN, XIA, QIU, DONG;
// CHUN(), XIA(), QIU(), DONG();//调用无参构造创建对象 小括号可以省略
// CHUN, XIA("夏天"), QIU("秋天"), DONG;//调用有参构造创建对象 需要传递对应的实参
CHUN, XIA("夏天") {
//花括号出现是 为了重写外部的方法
@Override
public String getName() {
return "夏天重写的代码";
}
}, QIU("秋天"), DONG;
private String name;
//枚举类型的构造器默认全部都是私有化的 而且必须是private修饰
private JiJie() {
}
private JiJie(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
1,枚举类型的基本使用
/**
* 枚举类型的基本使用
*/
private static void method1() {
JiJie chun1 = JiJie.CHUN;
JiJie chun2 = JiJie.CHUN;
JiJie xia = JiJie.XIA;
System.out.println(chun1 == chun2);
System.out.println(chun1);
System.out.println(chun1.getName());
System.out.println(xia.getName());
//通过继承获取的方法
System.out.println("name" + xia.name());
//对象的序号从0开始
System.out.println("序号:" + xia.ordinal());
}
2,在switch中的使用
/**
* 枚举类型在switch中应用
*
* @param jiJie
*/
private static void method2(JiJie jiJie) {
switch (jiJie) {
case CHUN:
System.out.println("");
break;
case XIA:
System.out.println("");
break;
case QIU:
System.out.println("");
break;
case DONG:
System.out.println("");
break;
default:
System.out.println("");
break;
}
}
3,枚举去设计单例
-
不管是反射还是反序列化都无法破坏 使用枚举设计的单例
public enum Singleton {
//单个实例
INSTANCE;
}
验证代码
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("./res/out.txt"));
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("./res/out.txt"))) {
Singleton instance = Singleton.INSTANCE;
objectOutputStream.writeObject(instance);
System.out.println("=======");
Object o = objectInputStream.readObject();
System.out.println(o);
System.out.println(instance);
System.out.println(o == instance);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void method4() throws ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("com.edu.www.day0512.Singleton");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
}
低耦合 高内聚
框架的配置文件 XML
.xml配置文件 ;灵活 低耦合的配置 ;维护成本过高
注解的出现 把要配置的信息直接写入源码中 耦合度增加了 维护成本降低了;
2.注解
-
注解 可以使用在 类,方法上 成员变量;
-
@Override;必须要有解析程序 如果没有解析程序 注解毫无作用
-
一类实在编译阶段被解析 一类是在运行阶段通过反射被解析
-
内置注解 提供好的可以直接使用的;自定义注解
-
注解的本质是接口类型,而且是继承了Annotation接口的接口类型
-
元注解 注解的注解 用来声明注解的
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
public interface Override extends Annotation{
}
1,元注解
@Target,此注解可以使用在哪些地方
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) 成员变量 */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration 局部变量 */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
}
@Retention:保留 期 表示这个注解能活多久
public enum RetentionPolicy {
/**
* 只存在与源文件中
*/
SOURCE,
/**
*可存在与 字节码文件中
*/
CLASS,
/**
* 可存活与 运行期
*/
RUNTIME
@Documented:此注解信息 是否要出现在JavaDoc 文档中
@Inherited:可以被继承的注解;子类可以直接继承父类上面的注解
2.1.自定义注解
1,基本使用
//注解类型
//@Target(ElementType.TYPE)
@Target({ElementType.TYPE, ElementType.METHOD})
//@Retention(value = RetentionPolicy.RUNTIME)
@Retention(RetentionPolicy.RUNTIME)
public @interface Description {
//注解中的成分只有一个 而且名称是value的时候在进行使用的时候可以直接赋值 value可以省略
// String value();
//基本数据类型,String,Class enum,Annotation;这写类型的数组也可以
String name();
String email();
}
应用
@Description(name = "father", email = "aa")
@Ano2
public class Father {
@Description(name = "study", email = "aa")
public void study() {
}
}
解析程序
/**
* 使用反射解析程序
*
* @throws ClassNotFoundException
* @throws NoSuchMethodException
*/
private static void method1() throws ClassNotFoundException, NoSuchMethodException {
Class<?> aClass = Class.forName("com.edu.www.day0512.anno1.Father");
//获取的是此类型上面 标注的所有注解
Annotation[] annotations = aClass.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
// 获取指定注解对象
Description annotation = aClass.getAnnotation(Description.class);
String name = annotation.name();
System.out.println(name);
String email = annotation.email();
System.out.println(email);
//获取方法上面的注解
Method declaredMethod = aClass.getDeclaredMethod("study");
Description annotation1 = declaredMethod.getAnnotation(Description.class);
}
2,测试框架的使用
自定义注解类型
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestEnable {
}
应用
public class Student {
@TestEnable
public void method1() {
System.out.println("method1");
}
public void method2() {
System.out.println("method2");
}
@TestEnable
public void method3() {
System.out.println("method3");
}
public void method4() {
System.out.println("method4");
}
}
解析程序
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException {
Class<?> aClass = Class.forName("com.edu.www.day0512.anno2.Student");
Object o = aClass.newInstance();
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
if (declaredMethod.isAnnotationPresent(TestEnable.class)) {
declaredMethod.invoke(o);
}
}
}
本文介绍了Java中的枚举类型,强调其固定对象和单例设计,以及如何通过枚举实现单例模式。同时,讲解了注解和元注解的概念,包括它们的作用和使用场景,以及如何通过反射解析自定义注解。
1308

被折叠的 条评论
为什么被折叠?



