反射和设计模式(笔记)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射和设计模式(笔记)相关的知识,希望对你有一定的参考价值。

参考技术A

1. 什么是反射及作用

动态获取类或对象信息以及动态调用对象方法的机制

作用:
获取类或接口的包名,类名,修饰符类型 获取类所包含的成员信息
白话文: 在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();
}
}

 

以上是关于反射和设计模式(笔记)的主要内容,如果未能解决你的问题,请参考以下文章

笔记之_java整理设计模式

设计模式笔记-代理模式

设计模式笔记-代理模式

JAVA的反射和工厂模式的例子实现

高级java思考笔记:反射的基本原理1

《JavaScript高级程序设计》笔记目录