1 反射

1、什么是反射?
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。

2、Class类
要利用反射,必须先得到代表字节码的Class。Class类用于表示.class文件(字节码)。

如何得到某个class文件对应的class对象。
1)类名.class,
2)对象.getClass()
3)Class.forName(“类名”)
4)基本类型的包装类.TYPE
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int,void…

3、解剖类
Class对象提供了如下常用方法:

public Constructor getConstructor(Class<?>…parameterTypes)
public Method getMethod(String name,Class<?>… parameterTypes)
public Field getField(String name) 

public Constructor getDeclaredConstructor(Class<?>…parameterTypes)
public Method getDeclaredMethod(String name,Class<?>… parameterTypes)
public Field getDeclaredField(String name)

这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、Method、Field对象表示。

4、利用Constructor创建对象
Constructor类提供了如下方法,用于创建类的对象:

public Object newInstance(Object…initargs)

initargs用于指定构造函数接收的参数

Constructor可以反射类无参、有参、私有的构造函数,创建类的对象

Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象。
String obj = (String)Class.forName("java.lang.String").newInstance()

5、利用Method调用方法
Method提供了如下方法,用于执行它所代表的方法

public Object invoke(Object obj,Object…args)

使用Method可以分别执行无参、有参、多参(带数组和基本数据类型)、静态、私有的方法

6、Field类
Field类代表某个类中的一个成员变量

f.get();
f.set();

包含私有变量、静态变量、公共变量

7、反射main方法
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:

mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了

0 Person类

public class Person {
    public String name="demoName";
    private int age = 18;
    public static Date time;
    
    public int getAge() {
        return age;
    }
    public Person(){
        System.out.println("默认构造方法执行了");
    }
    public Person(String name){
        System.out.println("姓名:"+name);
    }
    public Person(String name,int age){
        System.out.println(name+"="+age);
    }
    private Person(int age){
        System.out.println("年龄:"+age);
    }
    
    public void m1(){
        System.out.println("m1");
    }
    public void m2(String name){
        System.out.println(name);
    }
    public String m3(String name,int age){
        System.out.println(name+":"+age);
        return name+":"+age;
    }
    private void m4(Date d){
        System.out.println(d);
    }
    public static void m5(){
        System.out.println("m5");
    }
    private static void m6(String[] strs){
        System.out.println(strs.length);
    }
    public static void main(String[] args) {
        System.out.println("main");
    }
}

1 反射构造

public class Demo1 {
    //反射:public Person()
    @Test
    public void test1() throws Exception{
        //得到字节码
        Class clazz = Class.forName("cn.demo.base.reflect.Person");//代表Person类在内存中的字节码对象
//      Class clazz = p.getClass();
//      Class clazz = Person.class;
        Constructor c = clazz.getConstructor(null);//得到构造方法干嘛?创建对象
        c.newInstance(null);
        
    }
    @Test
    public void test11() throws Exception{
        Class clazz = Class.forName("cn.demo.base.reflect.Person");
        Person p = (Person)clazz.newInstance();//调用默认的构造方法
        System.out.println(p.name);
    }
    //反射:public Person(String name)
    @Test
    public void test2() throws Exception{
        //得到字节码
        Class clazz = Class.forName("cn.demo.base.reflect.Person");//代表Person类在内存中的字节码对象
        Constructor c = clazz.getConstructor(String.class);
        c.newInstance("朱巧玲");
        
    }
    @Test//public Person(String name,int age)
    public void test3() throws Exception{
        Class clazz = Class.forName("cn.demo.base.reflect.Person");
        Constructor c = clazz.getConstructor(String.class,int.class);
        Person p = (Person)c.newInstance("朱朱",20);
        System.out.println(p.name);
        
    }
    @Test//private Person(int age)
    public void test4() throws Exception{
        Class clazz = Class.forName("cn.demo.base.reflect.Person");
        Constructor c = clazz.getDeclaredConstructor(int.class);//读取私有的构造方法的
        c.setAccessible(true);//暴力反射
        Person p = (Person)c.newInstance(20);
        System.out.println(p.name);
        
    }
    @Test//类中的所有构造方法
    public void test5() throws Exception{
        Class clazz = Class.forName("cn.demo.base.reflect.Person");
        Constructor[]  cs = clazz.getDeclaredConstructors();
        System.out.println(cs.length);
        
    }
}

2 反射类中的方法

public class Demo2 {
    //public void m1()
    @Test
    public void test1() throws Exception{
        Class clazz = Person.class;
        Person p = (Person) clazz.newInstance();
        Method m = clazz.getMethod("m1", null);//得到方法干嘛?
        m.invoke(p, null);
    }
    @Test//public void m2(String name)
    public void test2() throws Exception{
        Class clazz = Person.class;
        Person p = (Person) clazz.newInstance();
        Method m = clazz.getMethod("m2", String.class);//得到方法干嘛?
        m.invoke(p, "葛付以");
    }
    @Test//public String m3(String name,int age)
    public void test3() throws Exception{
        Class clazz = Person.class;
        Person p = (Person) clazz.newInstance();
        Method m = clazz.getMethod("m3", String.class,int.class);//得到方法干嘛?
        String returnValue = (String)m.invoke(p, "葛付以",23);
        System.out.println(returnValue);
    }
    @Test//private void m4(Date d)
    public void test4() throws Exception{
        Class clazz = Person.class;
        Person p = (Person) clazz.newInstance();
        Method m = clazz.getDeclaredMethod("m4", Date.class);//得到方法干嘛?
        m.setAccessible(true);
        m.invoke(p,new Date());
    }
    @Test//public static void m5()
    public void test5() throws Exception{
        Class clazz = Person.class;
        Method m = clazz.getMethod("m5", null);//得到方法干嘛?
        m.invoke(null,null);
    }
    @Test//private static void m6(String[] strs)
    public void test6() throws Exception{
        Class clazz = Person.class;
        Method m = clazz.getDeclaredMethod("m6",String[].class);//得到方法干嘛?
        m.setAccessible(true);
        m.invoke(null,(Object)new String[]{"a","b"});
    }
    @Test
    public void test7() throws Exception{
        Class clazz = Person.class;
        Method m = clazz.getMethod("main",String[].class);//得到方法干嘛?
        m.invoke(null,new Object[]{new String[]{"a","b"}});
    }
}

3 反射字段:Field

public class Demo3 {
    
    @Test
    public void test1() throws Exception{
        Class clazz = Person.class;
        Person p = (Person)clazz.newInstance();
        Field f = clazz.getField("name");
        String s = (String)f.get(p);
        System.out.println(s);
        
        //更改name的值
        f.set(p, "上海");
        System.out.println(p.name);
    }
    @Test//private int age = 18;
    public void test2() throws Exception{
        Class clazz = Person.class;
        Person p = (Person)clazz.newInstance();
        Field f = clazz.getDeclaredField("age");
        f.setAccessible(true);
        int age = (Integer)f.get(p);
        System.out.println(age);
        
        f.set(p, 28);
        age = (Integer)f.get(p);
        System.out.println(age);
    }
    @Test//public static Date time;
    public void test3() throws Exception{
        Class clazz = Person.class;
        Field f = clazz.getField("time");
        f.set(null, new Date());
        System.out.println(Person.time);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,204评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,091评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,548评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,657评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,689评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,554评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,302评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,216评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,661评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,851评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,977评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,697评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,306评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,898评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,019评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,138评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,927评论 2 355

推荐阅读更多精彩内容

  • 转自https://blog.csdn.net/sinat_38259539/article/details/71...
    扎Zn了老Fe阅读 473评论 0 4
  • 这是16年5月份编辑的一份比较杂乱适合自己观看的学习记录文档,今天18年5月份再次想写文章,发现简书还为我保存起的...
    Jenaral阅读 2,756评论 2 9
  • 蒹葭苍苍 蒹葭苍苍露凝霜, 伊人遥遥思成殇。 思成殇兮奈若何, 胜雪芦花满堤岸。 渡 锦书何处寄,轻舟独自横。 枫...
    胡美云阅读 320评论 4 8
  • 昨晚老师打电话要来家里,开学前家访。小朋友对于老师的到来又开心,又有点紧张。老师来家里是开心的,但总感觉老师来是来...
    晓言晓语阅读 461评论 0 3
  • 本文搜集整理了36个绝对不能错过的excel使用技巧大全,个个都很实用。 1、一列数据同时除以10000 复制10...
    xingkong_hdc阅读 47,091评论 0 4