java反射:通用编程常用 设计模式

tech2022-09-14  104

java反射:通用编程

类对象:类加载的产物,封装了一个类的所有信息,类对象的各个组成部分都是对象

public class Test { public static void main(String[] args) throws Exception { Student student = new Student(); Teacher teacher = new Teacher(); System.out.println(student.getClass().getName()); System.out.println(teacher.getClass().getPackage()); System.out.println(student.getClass().getSuperclass()); System.out.println(teacher.getClass().getFields()); //获得对象的多种方式 //1。 通过类的对象获得 Class c1 = new Student().getClass(); //2。 通过类名获得 保证类必须存在 Class c2 = Dog.class; //3。 通过静态方法获得 不必保证该包必须存在 推荐 Class c3 = Class.forName("com.qianfeng.classs.Dog"); } } class Student {} class Teacher {} class Dog{} 相关方法: public String getName() //获得类名 public Package getPackage() //获得包名 public Class<?> getSuperclass() //获得父类 public class<?>[] getInterfaces() //获得实现的接口的class对象 public Field[] getFields() //获得公开的属性 包括子类的公开属性 public Fileds[] getDeclaredFields() // 获得所有的属性 public Method[] getMethods() //获得公开方法 包括子类的公开方法 public Method getMethod("study", int.class) //获得方法名为study,参数类型为int的方法 public Method[] getDeclaredMethods() //获得所有方法 public Constructor<?>[] getConstructors //获得公开构造方法 public Constructor<?>[] getDeclaredConstructors //获得所有构造方法 public T newInstance() // new一个实例,,频繁的修改 创建的对象 优势大 //每次只需传一个类名即可创建返回该对象的实例,类名的获得可以通过流获取 public static Object factory(String classname) throws Exception{ Class c = Class.forName(classname); return c.newInstance(); } Invoke 执行该方法 public class Invoke { public static void main(String[] args) { Object o = objectFactory("com.qianfeng.invoke.Student"); // 向objectFactory传送一个全限定名并接收返回的对象 try { // 通过对象获得类对象,获得名为study 参数为String的方法 Method m = o.getClass().getMethod("study", String.class); // invoke执行方法,两个参数,一个是 对象,第二个是所需方法的实参 m.invoke(o, "数学"); // 相当于 new Student().study("数学"); //如果该方法是私有的,可以通过setAccessible(boolen) 来设置是否可以访问 //java反射是一种java底层技术,可以突破封装 //m.setAccessible(true) 设置该方法可以被访问 } catch (Exception e) { e.printStackTrace(); } } // objectFactory工厂,传入一个全限定名(包名+类名),返回一个该对象 public static Object objectFactory(String className) { try { Class c = Class.forName(className); return c.newInstance(); // 创建对象并返回 } catch (Exception e) { e.printStackTrace(); } return null; } } class Student { private String name; public void study() { System.out.println(); } public void study(String subject) { System.out.println(name + "学习" + subject); } public void eat() { System.out.println(); } }

设计模式:

​ 设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性

​ 1:工厂模式 一个工厂类根据传入的参量决定创建出那一种产品类的实例。 ​ 2:单例模式 某个类只能有一个实例,提供一个全局的访问点。 ​ 3:监听者模式 事件源经过事件的封装传给监听器,当事件源触发事件后,监听器接收到事件对象可以回调事件的方法 ​ 4:代理模式 为其他对象提供一个代理以便控制这个对象的访问。 ​ 5:适配器模式 将一个类的方法接口转换成客户希望的另外一个接口。 ​ 6:观察者模式 对象间的一对多的依赖关系。 ​ 7:装饰者模式 动态的给对象添加新的功能。 ​ 8 消费生产者模式 主要是将生产者与消费者解耦,通过一个容器来解决生产者和消费者的强耦合问题,生产者消费者彼此之间通过阻塞队列来进行通讯 ​

23种设计模式详解: https://www.cnblogs.com/pony1223/p/7608955.html 单例模式: 背过 //方式 1 饿汉式(类加载时创建,天生线程安全 public class Singleton { public static final Singleton instence = new Singleton(); private Singleton() { } public static Singleton getInstence() { return instence; } } //懒汉式 (使用时创建,线程不安全,加同步) class Singleton2 { private static Singleton2 instence = null; private Singleton2() { } public static synchronized Singleton2 getInstence() { if (instence == null) { instence = new Singleton2(); } return instence; } } //懒汉式 (使用时创建,线程安全) class Singleton3 { private Singleton3() { } private static class Hold { static Singleton3 s = new Singleton3(); } public static Singleton3 instence() { return Hold.s; } } 通用编程: public class All { public static void main(String[] args) throws Exception{ invokeAll(new Teacher(), "teach", new Class[]{String.class}, "数学"); } // 定义一个方法,传入对象,方法名 ,参数列表(参数类型,参数值) object... 是可变长参数 public static void invokeAll(Object o, String methodName, Class[] type, Object... objects) throws Exception { //调用方法,就要先得到类对象 //通过对象获得类对象 Class class1 = o.getClass(); //通过类对象获得方法名 Method m = class1.getMethod("teach", type); //执行方法 m.invoke(o, objects); } } class Teacher{ public void teach(String subject) { System.out.println("教"+subject); } }

枚举:

枚举是一个引用类型,规定了取值范围的数据类型

枚举变量不能使用其他的数据,只能使用枚举中常量赋值,提高代码的安全性

定义枚举用enum关键字

阿里编码规范:枚举文件以Enum结尾

枚举是一个终止类,,继承Enum抽象类,枚举中的常量是当前类型的静态常量

代码中不能有字符串的出现,所有字符串都应该在枚举类中定义,调用相应的属性即可

public enum LoginEnum { // value desc 可以通过调用getvalue,getdesc来获得 相应字符串 USER_NAME_IS_FAIL("USER_NAME_IS_FAIL", "用户名错误"), USER_NAME_IS_NULL("USER_NAME_IS_NULL", "用户名为空"), USER_PASSWORD_IS_FAIL("USER_PASSWORD_IS_FAIL", "用户密码错误"), USER_PASSWORD_IS_NULL("USER_PASSWORD_IS_NULL", "密码为空"), USER_NAME_LENGTH_IS_FAIL("USER_NAME_LENGTH_IS_FAIL", "用户名长度错误"), USER_PASSWORD_LENGTH_IS_FAIL("USER_PASSWORD_LENGTH_IS_FAIL", "密码长度错误"); private String value; private String desc; private LoginEnum(String value, String desc) { this.value = value; this.desc = desc; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } }

注解:

自定义注解用@interface修饰,注解本身就是一个接口,实现了Annotation接口

注解属性类型:

1. String类型 2. 基本数据类型 3. Class类型 4. 枚举类型 5. 注解类型 6. 以上类型的一维数组

元注解:用来描述注解的注解

@Retention :用来指定注解可以保留的域

​ 用法:@Retention (RetentionPolicy.RUNTIME)

1. .CLASS(表示该注解记录在class文件中,运行java程序时JVM不会保留,此为默认值) 2. .RUNTIME(表示该注解记录在class文件中,运行Java程序时,JVM会保留,程序可以通过反射获得该注解) 3. .SOURCE ( 编译时直接丢弃这种策略的注解)

@Target : 指定注解用于修饰类的那个成员

​ 用法 : @Target(ElementType.FIELD)

@Retention(RetentionPolicy.RUNTIME) //记录在class文件中,运行时保留 @Target(ElementType.FIELD) //用在属性上 public @interface AgeValidate { //default设置默认值 boolean age() default false; }
最新回复(0)