反射和设计模式(笔记)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射和设计模式(笔记)相关的知识,希望对你有一定的参考价值。
参考技术A1. 什么是反射及作用
动态获取类或对象信息以及动态调用对象方法的机制
作用:
获取类或接口的包名,类名,修饰符类型 获取类所包含的成员信息
白话文: 在java程序运行的时候,我们可以拿到一个类的任意方法及变量,
并且可以调用任意方法,更改任意变量
应用最广泛的地方:
配合注解使用,注解的底层都是反射.
2. 使用反射获取Class****对象的三种方式
a. Class的forName() --- Class.forName(“com.bwie.Student”)//参数是全类名
b. 对象的getClass() --- new Student().getClass()
c. 类的class属性 --- Student.class
3. 获取Class****对象对应类所包含的构造方法 (构造器Constructor****)
getConstructor() 获取一个由public修饰的构造函数
getConstructors() 获取所有由public修饰的构造函数
getDeclaredConstructor() 获取一个非公共的构造函数 (包含私有 公共)
getDeclaredConstructors() 获取所有的构造函数 (包含私有 公共)
4. 获取Class****对象对应类所包含的成员变量 (属性Field****)
getField() 获取一个由public修饰的成员变量
getFields() 获取所有由public修饰的成员变量
getDeclaredField() 获取一个非公共的成员变量 (包含私有 公共)
getDeclaredFields() 获取所有的成员变量 (包含私有 公共)
5. 获取Class****对象对应类所包含的成员方法 (属性Method****)
getMethod() 获取一个由public修饰的成员方法
getMethods() 获取所有由public修饰的成员方法
getDeclaredMethod() 获取一个非公共的成员方法 (包含私有 公共)
getDeclaredMethods() 获取所有的成员方法 (包含私有 公共)
获取Class****对象的修饰符类型Modifier
6. 通过反射创建对象的两种方式
a. 使用Class对象的newInstance()
如 Class<?> cls = Student.class
cls.newInstance() 注意:该方式只能通过无参构造创建对象
b. 使用Constructor对象的newInstance()
如 Class<?> cls = Student.class
Constructor con = cls.getConstructor()
con.newInstance(注意:该方式可以通过无参构造和有参构造来创建对象)
7. 使用反射访问成员方法
通过Method****类的invoke()****方法进行方法调用
//访问权限的设置 当我们想调用私有方法,更改私有属性的时候,必须先把
该方法/该属性,设置如下(暴力反射)
xxx.setAccessible(true)
8. 什么是设计模式
软件开发过程中共性问题的可重用解决方案
外延:单例模式 工厂模式 适配器模式 代理模式(动态代理和静态代理)
单例模式确保一个类只能创建一个实例的设计模式
9. 设计模式小结
个人笔记仅供参考!
笔记之_java整理设计模式
设计模式分类: 创建型:new方法,实例化 结构型:类的结合,套用 行为型:方法的操作 必须掌握的设计模式:工厂、模板、单例、命令、适配器、代理 接口先定义,后实现 抽象类与接口: 光用继承会导致,父类一改变,子类就不得不改变,代码可复用 光用接口子类必须要重写父类所有方法,代码不能复用 反射机制: 反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制 反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法; 生成动态代理。 通过一个对象获得完整的包名和类名 new 类名().getClass().getName() 获得类 Class.forName("net.xsoftlab.baike.TestReflect"); new TestReflect().getClass(); TestReflect.class; 获取一个对象的父类与实现的接口 取得父类 Class<?> parentClass = clazz.getSuperclass(); 获取所有的接口 Class<?> intes[] = clazz.getInterfaces(); 通过反射机制实例化一个类的对象 实例化默认构造方法 User user = (User) class1.newInstance() 取得全部的构造函数 使用构造函数赋值 Constructor<?> cons[] = class1.getConstructors(); 取得构造函数的参数 cons[i].getParameterTypes(); 取得本类的全部属性 Field[] field = clazz.getDeclaredFields(); 权限修饰符 int Modifier= field[i].getModifiers(); String priv = Modifier.toString(mo); 属性类型 Class<?> type = field[i].getType(); 取得实现的接口或者父类的属性 Field[] filed1 = clazz.getFields(); 取得类的全部方法 Method method[] = clazz.getMethods(); 取得方法返回值类型 Class<?> returnType = method[i].getReturnType(); 取得方法参数 Class<?> para[] = method[i].getParameterTypes(); 取得方法修饰符 int temp = method[i].getModifiers(); 取得方法异常类型 Class<?> exce[] = method[i].getExceptionTypes(); 通过反射机制调用某个类的方法 Method method = clazz.getMethod("reflect1"); method.invoke(clazz.newInstance()); 通过反射机制操作某个类的属性 可以直接对 private 的属性赋值 Field field = clazz.getDeclaredField("proprety"); field.setAccessible(true); field.set(obj, "Java反射机制"); 在泛型为Integer的ArrayList中存放一个String类型的对象 public static void main(String[] args) throws Exception { ArrayList<Integer> list = new ArrayList<Integer>(); Method method = list.getClass().getMethod("add", Object.class); method.invoke(list, "Java反射机制实例。"); System.out.println(list.get(0)); } 通过反射修改数组的值 Array.set(temp, 0, 100); 通过反射机制修改数组的大小 System.arraycopy(旧数组名, 0,新数组名, 0, 旧数组长度); 设计模式:前辈程序员在解决具体的程序开发问题时给出的方案经验 单例模式:程序中对于某个类型的对象只能有一份 构造方法私有化 创建静态的唯一对象,初值为null 提供公共的静态方法返回唯一对象(判断对象是否已被实例化过) public class SingletonClass{ private static SingletonClass instance=null; private SingletonClass(){ } public static synchronized SingletonClass getInstance(){ if(instance==null){ instance=new SingletonClass(); } return instance; } } 递归调用: public class Test{ public static void main(String[] args) { System.out.println(method(5)); } public static int method(int n){ if (n == 1){ return 1; }else{ return n * method(n-1); } } } 代理模式: 为其他对象提供一种代理,并以控制对这个对象的访问 代理模式在不同的场景,都会要建立不同的接口,导致代码不能复用 Java中提供了一种反射机制叫做动态代理 在java的动态代理机制中,有两个重要的类或接口, 一个是 InvocationHandler(Interface) InvocationHandler这个接口的唯一一个方法 invoke 方法: Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy: 指代我们所代理的那个真实对象 method: 指代的是我们所要调用真实对象的某个方法的Method对象 args: 指代的是调用真实对象某个方法时接受的参数 另一个则是 Proxy(Class) Proxy这个类的作用就是用来动态创建一个代理对象的类 public static Object newProxyInstance( ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException loader: 一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载 interfaces: 一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了 h: 一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上 代理实例: 代理公共接口: public interface ReadInterface { public void reader(); } 被代理人(客户): public class person implements ReadInterface{ @Override public void reader() { System.out.println("---------现在开始读书---------"); System.out.println("---------读了一章---------"); System.out.println("---------又读了一章--------"); System.out.println("---------这一章节很精彩---------"); System.out.println("---------读了一天了---------"); System.out.println("---------读完了---------"); } } 代理人: public class ProxyRead implements InvocationHandler{ private Object subject; public ProxyRead(Object subject) { this.subject = subject; } public Object createProxy(){ return Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long begin=System.currentTimeMillis(); System.out.println("--------万能代理类开始做事情----------"); Object obj=method.invoke(subject, args); System.out.println("--------万能代理类做完做事情----------"); long end=System.currentTimeMillis(); System.out.println("执行程序花了"+(end-begin)*1.0/1000+"秒"); return obj; } } 测试类: public class Test { public static void main(String[] args) { ProxyRead pr=new ProxyRead(new person()); ReadInterface read=(ReadInterface) pr.createProxy(); read.reader(); } } 将反射机制应用于工厂模式 interface fruit { public abstract void eat(); } class Apple implements fruit { public void eat() { System.out.println("Apple"); } } class Orange implements fruit { public void eat() { System.out.println("Orange"); } } class Factory { public static fruit getInstance(String ClassName) { fruit f = null; try { f = (fruit) Class.forName(ClassName).newInstance(); } catch (Exception e) { e.printStackTrace(); } return f; } } 策略模式:将可变的能力设为接口,在公共的父类中,设为变量,并调用其方法,另有子类实现接口,并在具体继承抽象父类时为接口变量赋值 抽象父类: public abstract class Duck { private FlyAble flyAble = null; public void setFlyAble(FlyAble flyAble) { this.flyAble = flyAble; } public void fly() { // 飞对象.飞(); flyAble.fly(); } public void swim() { System.out.println("浮水......"); } public abstract void dispaly(); } 接口: public interface FlyAble { public void fly(); } 接口实现: public class RocketFly implements FlyAble{ @Override public void fly() { System.out.println("借助火箭飞........"); } } public class WingFly implements FlyAble { @Override public void fly() { System.out.println("用本身翅膀飞....."); } } 继承抽象类: public class RedDuck extends Duck{ public RedDuck() { super.setFlyAble(new WingFly()); } @Override public void dispaly() { System.out.println("红头鸭,头是红的"); } } 测试: public class Test { public static void main(String[] args) { test3(); } public static void test3(){ Duck duck=new RedDuck(); //变性的 吱吱叫 //火箭 绑上去,看一看飞行效果 duck.setFlyAble(new RocketFly()); duck.dispaly(); duck.swim(); duck.fly(); } } 模板模式: public class Benz{ public void start(){ System.out.println(“奔驰车启动”); } public void trunLeft(){ System.out.println(“奔驰车左转弯”); } public void alerm(){ System.out.println(“奔驰车响笛一声”); } public void stop(){ System.out.println(“奔驰车停车”); } } public class BMW{ public void start(){ System.out.println(“宝马车启动”); } public void trunLeft(){ System.out.println(“宝马车左转弯”); } public void alerm(){ System.out.println(“宝马车响笛一声”); } public void stop(){ System.out.println(“宝马车停车”); } } 模板: public abstract class Car{ public abstract void start() public abstract void trunLeft(); public abstract void alerm(); Public abstract void stop(); public void begin(){ this.start(); this.trunLeft(); this.alerm(); this.stop(); } }
以上是关于反射和设计模式(笔记)的主要内容,如果未能解决你的问题,请参考以下文章