单例模式 单例 单个实例 某种类型只能有单个对象
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); } } }