JAVA反射.docx

上传人:b****4 文档编号:7003955 上传时间:2023-05-10 格式:DOCX 页数:18 大小:227.61KB
下载 相关 举报
JAVA反射.docx_第1页
第1页 / 共18页
JAVA反射.docx_第2页
第2页 / 共18页
JAVA反射.docx_第3页
第3页 / 共18页
JAVA反射.docx_第4页
第4页 / 共18页
JAVA反射.docx_第5页
第5页 / 共18页
JAVA反射.docx_第6页
第6页 / 共18页
JAVA反射.docx_第7页
第7页 / 共18页
JAVA反射.docx_第8页
第8页 / 共18页
JAVA反射.docx_第9页
第9页 / 共18页
JAVA反射.docx_第10页
第10页 / 共18页
JAVA反射.docx_第11页
第11页 / 共18页
JAVA反射.docx_第12页
第12页 / 共18页
JAVA反射.docx_第13页
第13页 / 共18页
JAVA反射.docx_第14页
第14页 / 共18页
JAVA反射.docx_第15页
第15页 / 共18页
JAVA反射.docx_第16页
第16页 / 共18页
JAVA反射.docx_第17页
第17页 / 共18页
JAVA反射.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

JAVA反射.docx

《JAVA反射.docx》由会员分享,可在线阅读,更多相关《JAVA反射.docx(18页珍藏版)》请在冰点文库上搜索。

JAVA反射.docx

JAVA反射

java中的反射总结

刚开始学习java的时候真的很难理解反射到底是个什么东西

一些书籍,哪怕是很经典的书籍都解释的让人感觉懵懵的,或许的确是我太笨

况且,网上说在将来学习框架的时候需要经常应用到反射机制,这样一来总让人心里有些不安

就方才偶然又把讲解反射的章节和视频看了一点,觉得能理解一些了

现在决定一鼓作气,边看边写,顺便把一些主要的内容和操作都记载到这里

我想,对于我这么一个笨笨的人来说,学习的最好方法也许就是不断重复

遇到不懂的知识就停下来把以往的重新学一遍,虽然浪费了很多时间,但对我也有些效果

 

我的理解是:

所谓反射,就是根据一个已经实例化了的对象来还原类的完整信息

至少对我而言,我认为它带给我的好处是,让我从下往上的又了解了一遍面向对象

x_x在此又痛恨一边那些厚部头们,把我的脑细胞搞死一片

 

Class类

如果要完成反射,那么必须了解Class类

实例1:

通过对象取得包名和类名

1

2

3

4

5

6

7

8

9

10

11

12

13

package org.siu;

 

class Test{

     

}

 

public class Demo{

    public static void main(String[]args){

        Testt= new Test();

        System.out.println(t.getClass());

        System.out.println(t.getClass().getName());

    }

}

编译结果如下,注意包的编译方式即可

此处的getClass()方法是默认继承自Object类的

 

在java中,Object类是所有类的父类,同样,所有类的实例化对象也都是Class类的实例

因此,这样一来就会牵扯到向上转型和向下转型的概念

由于向下转型的不安全因素,在这里泛型也会接踵而来

(不过我想说的是,此处的泛型设计很刺眼!

尼玛,整个java的语法设计同样刺眼,超恶心!

 

实例2:

Class类的实例化

由于Class类没有构造方法,所以实例化Class类的方式有点特殊,有三种方式:

∙对象.getClass()

∙类.Class

∙forName()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

class Test{

     

}

 

public class Demo{

    public static void main(String[]args){

        //方式一:

        Testt= new Test();

        Class

 extends Test>c1=t.getClass();

        System.out.println(c1);

         

        //方式二:

        //为了避免特殊性,这里不用Test类,而用java库中的String类

        Classc2=String.class;

        System.out.println(c2);

         

        //方式三:

        //forName()方法会抛出异常

        Class

>c3= null;

        try {

            c3=Class.forName("Test");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        System.out.println(c3);

    }

}

 其中,forName()方法需要重点掌握,因为它可以在类不确定的情况下实例化Class,更具灵活性

 

Class类的应用

Class类中有一个方法叫做newInstance(),它可以用来创建一个Class类对象的新实例

怎么说呢?

Class对象包含的内容就是反射好的那个类,我们要构造那个类的新实例(新对象)

实例3:

Class类的无参构造对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

public class Demo{

    public static void main(String[]args){

        //实例化Class对象,forName()方法会抛异常

        Class

>c= null;

        try {

            //这里需要完整的包名和类名

            c=Class.forName("java.lang.String");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

         

        //生成一个字符串的引用

        Strings= null;

        try {

            //将构造好的对象向下转型为String类

            //newInstance()方法会抛异常

            s=(String)c.newInstance();

        } catch (InstantiationExceptione){

            e.printStackTrace();

        } catch (IllegalAccessExceptione){

            e.printStackTrace();

        }

        System.out.println("字符串长度:

" +s.length());

    }

}

这样就通过无参数的形式构造了一个新的对象,如同正常模式中

通过无参构造方法来构造新对象一样

我们知道,类中除了有无参构造方法,还会存在有参数的构造方法

那在反射中如何通过有参数的形式构造对象呢?

接着看

 

实例4:

Class类的有参构造对象

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

import java.lang.reflect.Constructor;

 

public class Demo{

    //下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

            c=Class.forName("java.lang.String");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        char[]ch={'h','e','l','l','o'};

        Strings= null;

        //获得Class类对象的有参构造方法,括号里面参数的写法是:

类型.class

        Constructor

>con=c.getConstructor(char[].class);

        //用此构造方法构造一个新的字符串对象,参数为一个char数组

        s=(String)con.newInstance(ch);

        System.out.println("构造的字符串:

" +s);

    }

}

我们还是使用String类做例,因为String类用的比较多,便于理解

这里需要注意的是,构造方法需要使用getConstructor()方法获得

至于参数类型则是:

原有类型.class

还有一点,无论是有参还是无参,这里所使用的构造方法,原本的类里面必须对应存在

那么,如何才能知道原有类里面的构造方法,普通方法,继承的父类等详细信息呢?

接着看

 

获取类的结构

要通过反射获取类的结构我们这里要导入一个新的包java.lang.reflect

实例5:

取得类的构造方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

import java.lang.reflect.Constructor;

import java.util.Arrays;

 

public class Demo{

    //下面的几个方法抛出来的异常太多,为了代码的紧凑性,这里就直接抛给虚拟机了

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

            c=Class.forName("java.lang.Boolean");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        //这里的getConstructors()方法返回的是一个Constructor数组

        Constructor

>[]cons=c.getConstructors();

        //打印的方式你可以自己写,为了方便我用Arrays.toString(),凑合着看

        System.out.println(Arrays.toString(cons));

    }

}

 我选择了Boolean类来做例,因为Boolean类的构造方法就两个,方便看

 

实例6:

取得类所实现的接口

1

2

3

4

5

6

import java.util.Arrays;

 

public class Demo{

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

7

8

9

10

11

12

13

14

            c=Class.forName("java.lang.Boolean");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        Class

>[]in=c.getInterfaces();

        System.out.println(Arrays.toString(in));

    }

}

 没什么好说的,看结果

 

实例7:

取得父类

1

2

3

4

5

6

7

8

9

10

11

12

13

public class Demo{

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

            c=Class.forName("java.lang.Boolean");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        //注意了,这里不会是数组,why?

        Class

>su=c.getSuperclass();

        System.out.println(su);

    }

}

 别忘了,java中是单继承,父类只有一个

 

实例8:

取得类的全部方法

1

import java.lang.reflect.Method;

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 

public class Demo{

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

            c=Class.forName("java.lang.Boolean");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

        Method[]m=c.getMethods();

        //好吧,这次我就大发慈悲的写个打印列表出来

        for (int i= 0;i

            System.out.println(m[i]);

        }

    }

}

 截取一部分,看看,意思下就行了……这几个例子都比较简单

 

实例9:

取得本类的全部属性

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import java.lang.reflect.Field;

 

class Person{

    private Stringname;

    private int age;

}

 

public class Demo{

    public static void main(String[]args) throws Exception{

        Class

>c= null;

        try {

            c=Class.forName("Person");

        } catch (ClassNotFoundExceptione){

            e.printStackTrace();

        }

16

17

18

19

20

21

        Field[]f=c.getDeclaredFields();

        for (int i= 0;i

            System.out.println(f[i]);

        }

    }

}

getDeclaredFielsd()方法可以获取全部属性,getFields()只能获取公共属性

 

实例10:

获取本类中属性的值

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

import java.lang.reflect.Field;

 

class Person{

    public Stringname;

    private int age;

     

    public Person(Stringname, int age){

        this.name=name;

        this.age=age;

    }

}

 

public class Demo{

    public static void main(String[]args) throws Exception{

        Personp= new Person("zhangsan",12);

 

        Class

>c=p.getClass();

         

        //获取公共属性的值

        Fieldf1=c.getField("name");

        //get(p)表明要获取是哪个对象的值

        Stringstr=(String)f1.get(p);

        System.out.println("姓名:

" +str);

         

        //获取私有属性的值

        Fieldf2=c.getDeclaredField("age");

27

28

29

30

31

32

        //age是私有属性,所以要设置安全检查为true

        f2.setAccessible(true);

        int age=(int)f2.get(p);

        System.out.println("年龄:

" +age);

    }

}

 要注意的是:

setAccessible()方法可以设置是否访问和修改私有属性

 

坦白说,java学到现在我还没发现什么能亮瞎我钛金眼的知识在里边

每次都是写一堆繁琐的语法实现个小玩意儿,不然就是拼命调用API,拼命的抛异常

让本身显得不够紧凑的代码变得愈发累赘

如果我喜欢一门语言,在我利用它做出东西来之前,它本身的特性必须能够打动我

显然,java并不让我快乐,也许很多程序员跟我一样是被迫使用java的

仅以此来安抚我那颗孤独编码的心,下面接着看内容

 

反射的应用

实例11:

通过反射修改属性

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

import java.lang.reflect.Field;

 

class Person{

    private Stringname;

     

    public Person(Stringname){

        this.name=name;

    }

     

    public StringtoString(){

        return "姓名:

" + this.name;

    }

}

 

public class Demo{

16

17

18

19

20

21

22

23

24

25

26

27

28

    public static void main(String[]args) throws Exception{

        Personp= new Person("王二狗");

        System.out.println(p);

        Class

>c=p.getClass();

     

        //定义要修改的属性

        Fieldf=c.getDeclaredField("name");

        f.setAccessible(true);

        //修改属性,传入要设置的对象和值

        f.set(p, "张二蛋");

        System.out.println(p);

    }

}

 几个方法都是有联系的,如果看不懂就先熟悉上面几个例子

 

实例12:

通过反射调用方法

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

import java.lang.reflect.Method;

 

class Person{

    public void print(int i){

        System.out.println("我在写数字:

" +i);

    }

     

    public static void say(Stringstr){

        System.out.println("我在说:

" +str);

    }

}

 

public class Demo{

    public static void main(String[]args) throws Exception{

        Personp= new Person();

        Class

>c=p.getClass();

     

        //getMethod()方法需要传入方法名,和参数类型

        Methodm1=c.getMethod("print", int.class);

20

21

22

23

24

25

26

27

        //invoke()表示调用的意思,需要传入对象和参数

        m1.invoke(p, 10);

         

        Methodm2=c.getMethod("say",String.class);

        //这里的null表示不由对象调用,也就是静态方法

        m2.invoke(null, "你妹");

    }

}

这里演示了一个普通的有参方法和一个静态方法

既然有参数的都写出来了,那么无参的就更简单了,直接传入一个对象即可

 

实例13:

通过反射操作数组

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

import java.lang.reflect.Array;

 

public class Demo{

    public static void main(String[]args) throws Exception{

        int[]arr={1,2,3,4,5};

  

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2