java 反射机制及动态代理

反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

Java反射机制主要提供了以下功能:

在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
生成动态代理

Class 是一个类; 一个描述类的类.
   封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性.
下面我们以student为例 一一介绍

先说获取Class对象的三种方式
1.通过类名获取 类名.class
2.通过对象获取 对象名.getClass()
3.通过全类名获取 Class.forName(全类名)

   //类名.class
    Class<ConStudent> conSC = ConStudent.class;
    System.out.print("---------类名.class---------"+"\n");
    //对象名.getClass()
    ConStudent conStudent = new ConStudent();
    Class<? extends ConStudent> conSC1 = conStudent.getClass();
    System.out.print("---------对象名.getClass()---------"+"\n");
    //Class.forName(全类名)
    Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
    System.out.print("---------Class.forName(全类名)---------");

---------类名.class---------
静态代码:10
---------对象名.getClass()---------
静态代码:10
---------Class.forName(全类名)---------

public class ConStudent {

public static int number = 10;
static {
    System.out.print("静态代码:"+number+"\n");
}

}

通过以上方式可以看出 第二第三种方式是直接调用静态代码的 从方便和效率来看 第三中方式是最好的 第一种也不错 第二种是不推荐的 个人建议 仅供参考

现在说一下 Constructor

先看一下 实体类

/**

  • Constructor
    */
    public class ConStudent {

    public ConStudent(){
    System.out.print("ConStudent空参构造函数"+"\n");
    }

    public ConStudent(double score) {
    System.out.print("ConStudent有参构造函数"+"\n");
    }

    private ConStudent(int age) {
    System.out.print("ConStudent私有构造带参数"+age+"\n");
    }
    protected ConStudent(String name){
    System.out.print("ConStudent受保护的构造参数"+name+"\n");
    }

}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

    Class<?> conSC = Class.forName("com.reflection.ConStudent");
    Constructor<?>[] constructors = conSC.getConstructors();
    for (Constructor c :constructors){
        System.out.print("ReflectTest所有公有构造:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");

    Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
    for (Constructor c : declaredConstructors){

        System.out.print("ReflectTest所有构造方法:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor constructor = conSC.getConstructor();
    System.out.print("ReflectTest公有无参构造方法"+constructor+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
    System.out.print("ReflectTest私有构造方法"+declaredConstructor+"\n");
    declaredConstructor.setAccessible(true);
    Object o = declaredConstructor.newInstance(11);
    System.out.print("ReflectTest调用私有构造"+o+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
    declaredConstructor1.setAccessible(true);
    Object maoge = declaredConstructor1.newInstance("maoge");
    System.out.print("ReflectTest受保护的构造:"+maoge);

}

输出内容

ReflectTest所有公有构造:public com.reflection.ConStudent(double)
ReflectTest所有公有构造:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest所有构造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有构造方法:private com.reflection.ConStudent(int)
ReflectTest所有构造方法:public com.reflection.ConStudent(double)
ReflectTest所有构造方法:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest公有无参构造方法public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest私有构造方法private com.reflection.ConStudent(int)
ConStudent私有构造带参数11
ReflectTest调用私有构造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割线-------------
ConStudent受保护的构造参数maoge
ReflectTest受保护的构造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0

下面看一下 Filed
实体也是三个参数 代表三种权限

/**

  • Filed
    */
    public class FiledStudent {
    public int age;
    private String name;
    protected double score;

    @Override
    public String toString() {
    return "FiledStudent{" +
    "age=" + age +
    ", name='" + name + ''' +
    ", score=" + score +
    '}';
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public double getScore() {
    return score;
    }

    public void setScore(double score) {
    this.score = score;
    }
    }

private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
Field[] fields = filedSC.getFields();
for (Field f :fields){
System.out.print("ReflectTest所有公有的参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field age = filedSC.getField("age");
Object o = filedSC.getConstructor().newInstance();
age.set(o,11);
FiledStudent student = (FiledStudent) o;
System.out.print("ReflectTest获取公有参数:"+student.getAge()+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field[] declaredFields = filedSC.getDeclaredFields();
for (Field f :declaredFields){
System.out.print("ReflectTest获取所有参数:"+f+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Field name = filedSC.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"Maoge");

    System.out.print("ReflectTest获取指定的私有参数:"+student.getName()+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Field score = filedSC.getDeclaredField("score");
    score.setAccessible(true);
    score.set(o,9.8);
    System.out.print("ReflectTest获取受保护的参数:"+student.getScore());

}

下面看 mothed

/**

  • Method
    */
    public class MethodStudent{
    int age;
    String name;
    double score;

    public void showName( ){
    System.out.print("(公共)姓名:");
    }
    private void showAge(){
    System.out.print("(私有)年龄:");
    }
    protected void showScore(){
    System.out.print("(保护)分数:");
    }

    public String printName(String name){
    System.out.print("(公共string)name:"+name);
    return name;
    }
    private double printScore(double score){
    System.out.print("(私有double)score:"+score);
    return score;
    }
    protected int printAge(int age){
    System.out.print("(保护age)age:"+age);
    return age;
    }

}

private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
Method[] declaredMethods = methodSC.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.print("ReflectTest 获取所有的方法:"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method[] methods = methodSC.getMethods();
for (Method m : methods){
System.out.print("ReflectTest获取所有的公有方法"+m+"\n");
}
System.out.print("ReflectTest----------分割线-------------"+"\n");
Method score = methodSC.getDeclaredMethod("printScore", double.class);
Object o = methodSC.getConstructor().newInstance();
score.setAccessible(true);
Object invoke = score.invoke(o, 9.8);
System.out.print("ReflectTest调用制定的私有方法:"+invoke+"\n");
System.out.print("ReflectTest----------分割线-------------"+"\n");

    Method printName = methodSC.getMethod("printName", String.class);
    Object maoge = printName.invoke(o, "Maoge");
    System.out.print("ReflectTest公有有参数方法:"+maoge+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method showName = methodSC.getMethod("showName", null);
    System.out.print("ReflectTest公有无参方法:"+showName+"\n");
    System.out.print("ReflectTest----------分割线-------------"+"\n");
    Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
    printAge.setAccessible(true);
    Object invoke1 = printAge.invoke(o, 20);
    System.out.print("ReflectTest受保护的方法:"+invoke1);
}

这是反射的一些基础使用

下面说一下动态代理 (代理可以让我们的方法或者类进行功能扩展 解耦等好处)

新建一个接口

public interface Person {
void work();
}

新建一个接口实现类(被角色代理)

public class PersonImpl implements Person{

@Override
public void work() {
    System.out.print("i am PersonImpl.calss");

}

}

新建一个代理角色

public class PersonHandler implements InvocationHandler {
public Object px;

public PersonHandler(Object px) {
    this.px = px;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.print("do work"+"\n");
    return method.invoke(px,args);
}

}

绑定代理

public class PersonProxyTest {
public static void main(String[] args) {
Person person = new PersonImpl();
Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
o.work();
}

}

好了 本文到此结束 欢迎留言或私信

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容