反射
反射获取类对象
try { Class c = Class.forName("Client"); System.out.println(c);} catch (ClassNotFoundException e) { throw new RuntimeException(e);}
反射获取构造器对象
获取构造器对象
// 获取无参数的, public构造器 Class c = Class.forName("Client");// Constructor constructor = c.getConstructor(); System.out.println(constructor.getName() + "参数个数" + constructor.getParameterCount());
//获取所有的构造器 Class c = Class.forName("Client"); System.out.println(c);// 获取类中全部的构造器对象 Constructor[] constructors = c.getDeclaredConstructors();// 遍历构造器 for (Constructor constructor : constructors) { System.out.println(constructor.getName() + "参数个数======" + constructor.getParameterCount()); }
// 获取有参数的, public构造器 Class c = Class.forName("Client");// Constructor constructor = c.getConstructor(String.class); System.out.println(constructor.getName() + "参数个数" + constructor.getParameterCount());
使用构造器创建对象
// 获取有参数的, public构造器 Class c = Class.forName("Client");// Constructor constructor = c.getConstructor(String.class);// 如果构造器方法是私有的,那就使用setAccessible打开权限。进行暴力反射 constructor.setAccessible(true); Client client = (Client) constructor.newInstance("名称参数"); System.out.println(client.getName()); System.out.println(constructor.getName() + "参数个数" + constructor.getParameterCount());
反射技术,获取成员变量对象。并使用
// 获取所有的成员变量 Field[] fields = c.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); System.out.println(field.getName() + "类型" + field.getType()); }// 根据名字获取成员变量 Field field = c.getDeclaredField("name");
field.setAccessible(true);//成员变量是私有的话,强行打开权限field.set(client, "给成员对象赋值");
String name = (String) field.get(client);//获取成员变量的值
反射获取方法对象
// 获取方法 Method[] methods = c.getDeclaredMethods();// 遍历方法 for (Method method : methods) { System.out.println(method.getName() + "返回值类型" + method.getReturnType() + "获取参数类型" + method.getParameterTypes()); }// 获取单个方法 Method method = c.getDeclaredMethod("setName", String.class);
// 执行方法 method.invoke(client, "通过反射调用方法"); System.out.println(field.get(client));
反射的作用
ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(18); //想要添加一个字符串就需要使用反射 Class c = list.getClass();// 获取添加方法 Method add = c.getDeclaredMethod("add", Object.class);// 执行该方法 Object bo = add.invoke(list, "添加字符串"); System.out.println(bo); System.out.println(list);
true
[1, 18, 添加字符串]
使用另外一种方式也可以做到以上的效果
ArrayList list2 = list;list2.add("另外一个字符串");System.out.println(list2);//[1, 18, 添加字符串, 另外一个字符串]
反射的作用----通用框架的底层原理
try { PrintStream ps = new PrintStream(new FileOutputStream("data.txt", true));// 第一步,获取类队形 Class c = object.getClass(); ps.println("================" + c.getSimpleName() + "==============");// 第二步。获取类对象中的所有方法和成员变量// Method[] methods = c.getDeclaredMethods(); Field[] fields = c.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); String name = field.getName();// 获取成员变量的值 String value = field.get(object) + "";//通过运算的方式,将不同类型的值转化为字符串。不用强转是// 为了防止强转异常抛出 ps.println(name + "=" + value); } ps.close(); } catch (Exception e) { e.printStackTrace(); }
注解
@Target({ElementType.METHOD, ElementType.TYPE})//注解在类和成员方法上@Retention(RetentionPolicy.RUNTIME)public @interface Book { String value();//书名 double price();//价格 String[] authors();//作者}
@Book(value = "情深深域名梦",price = 120.5, authors = {"k", "Q"})public class BookStore { private String shopName; private List<Book> bookList; @Book(value = "方法注解",price = 120.5, authors = {"老巫婆"}) public void test() { }}
// 第一步,先得到类对象 Class c = BookStore.class;// 判断这个类上面是否有这个注解 if(c.isAnnotationPresent(Book.class)) {// 直接获取该注解对象 Book book = (Book) c.getDeclaredAnnotation(Book.class); System.out.println(book.value()); System.out.println(book.price()); System.out.println(Arrays.toString(book.authors()));// 获取所有的方法 Method[] methods = c.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(Book.class)) { Book book1 = method.getDeclaredAnnotation(Book.class); System.out.println(book1.value()); System.out.println(book1.price()); System.out.println(Arrays.toString(book1.authors())); } } }
public static void main(String[] args) {// 第一步得到类队形 Main main = new Main(); Class c = main.getClass();// 获取类对象所有的成员方法 Method[] methods = c.getDeclaredMethods();// 根据类对象,生成实例对象,首先找到够找到构造器对象// 遍历 for (Method method : methods) {// 判断方法是否是被注解 if(method.isAnnotationPresent(MyTest.class)){ try { method.invoke(main); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } } }
动态代理
接口
public interface Skill { public void jump(); public void song();}
类
public class Star implements Skill { private String name; public Star(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public void jump() { System.out.println(name+"正在跳舞"); } @Override public void song() { System.out.println(name + "正在唱歌"); }}
代理类
import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class StarAgentProxy { public static Skill getProxy(Star obj) {// 为明星对象创建一个代理对象 return (Skill) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object rs =method.invoke(obj, args); return rs; } }); }}
调用
Skill skill = StarAgentProxy.getProxy(new Star("杨超越")) ;skill.jump();;skill.song();