首页 > 其他 > 详细

Java反射学习笔记

时间:2014-03-13 15:50:07      阅读:439      评论:0      收藏:0      [点我收藏+]

一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分

反射技术用在哪里?在做框架时反射是一门不可或缺的技术。经常在配置文件中获取一个类的完整名称字符串,再创建出该类对象使用

 

要解剖一个类,首先就要得到这个类,加载这个类

Java中有个Class类用于代表某一个类的字节码

Class类既然代表某个类的字节码,它当然要提供加载某个类字节码的方法:forname().forName方法用于加载某个类的字节码到内存中,并使用class对象进行封装

下面是加载类的三种方式:

1
2
3
4
5
6
7
8
9
10
//加载类的三种方式
//  @Test
public void addClass() throws Exception{
//方式一:
Class<Person1> clazz1 = (Class<Person1>) Class.forName("peng.Demo.Person1");
//方式二:
Class<Person1> clazz2 = Person1.class;
//方式三:
Class<Person1> clazz3 = (Class<Person1>) new Person1().getClass();
}


  加载类后,如果要new出类对象,要需要解剖出构造方法

反射构造方法:

bubuko.com,布布扣
//反射构造函数
@Test
public void reflectCon() throws Exception{
Class<Person1> clazz = (Class<Person1>) Class.forName("peng.Demo.Person1");
//无参的构造函数
/*Constructor<Person1> con = clazz.getConstructor(null);
Person1 p = con.newInstance(null);
System.out.println(p.name);*/


//另外一个new出对象的方法,只能new无参的构造函数
Person1 per = clazz.newInstance();


//     //反射出带参的构造函数
//     Constructor con = clazz.getConstructor(String.class,int.class);
//     Person1 pp = (Person1) con.newInstance("啦啦啦",123455);

//反射出私有的构造函数
Constructor con = clazz.getDeclaredConstructor(List.class);
//暴力破解
con.setAccessible(true);
Person1 person = (Person1) con.newInstance(new ArrayList());
}
  
bubuko.com,布布扣

 

 

反射类字段:

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
28
29
30
31
32
33
34
35
36
37
//反射字段:public String name = "aaa"
@Test
public void test01() throws Exception{
//加载类
    Class clazz = Class.forName("peng.Demo.Person1");
    Field field = clazz.getField("name");
    Person1 p = (Person1) clazz.newInstance();
    //获取字段类型
    Class type = field.getType();
    if(type.equals(String.class)){
    System.out.println(field.get(p));
    }
 
    //设置字段
    field.set(p, "哈哈哈哈");
    System.out.println(p.name);
    }
    //反射字段:private int age = 14
    @Test
    public void test02() throws Exception{
    Class clazz = Class.forName("peng.Demo.Person1");
    Field field = clazz.getDeclaredField("age");
    Person1 p = (Person1) clazz.newInstance();
    //获取访问权限
    field.setAccessible(true);
    System.out.println(field.get(p));
    field.set(p, 123);
    System.out.println(field.get(p));
}
    //反射字段:public static double dou = 12.21
    @Test
    public void test03() throws Exception, SecurityException{
    Class clazz = Class.forName("peng.Demo.Person1");
    Field field = clazz.getField("dou");
    Person1 p = (Person1) clazz.newInstance();
    System.out.println(field.get(p));
}   

  

 反射出类方法:

bubuko.com,布布扣
//反射:public void demo()
@Test
public void test1() throws ClassNotFoundException,     Throwable, SecurityException{
    Class clazz = Class.forName("peng.Demo.Person1");
    Person1 p = (Person1) clazz.newInstance();
    Method method = clazz.getMethod("demo", null);
    method.invoke(p, null);
}
    //反射:public void demo(String name,int password)
    @Test
    public void test2() throws Exception{
    Class clazz = Class.forName("peng.Demo.Person1");
    Person1 p = (Person1) clazz.newInstance();
    Method method = clazz.getMethod("demo",                    String.class,int.class);
    method.invoke(p, "哈哈哈",1233);

}
//反射:public Class[] demo(String name)
    @Test
    public void test3() throws Exception{
        Class clazz = Class.forName("peng.Demo.Person1");
        Person1 p = (Person1) clazz.newInstance();
    Method method = clazz.getMethod("demo", String.class);
    Class[] cls = (Class[]) method.invoke(p, "haha");
    System.out.println(cls[0]);
}
    //反射: private void demo(int password)
    @Test
    public void test4() throws Exception{
    Class clazz = Class.forName("peng.Demo.Person1");
    Person1 p = (Person1) clazz.newInstance();
    Method method = clazz.getDeclaredMethod("demo",     int.class);
    method.setAccessible(true);
    method.invoke(p, 11);
}
    @Test
    //反射:public static void demo(List list)
    public void test5() throws Exception{
    Class clazz = Class.forName("peng.Demo.Person1");
    Person1 p = (Person1) clazz.newInstance();
    Method method = clazz.getMethod("demo", List.class);
    method.invoke(p, new ArrayList());
    //其实直接通过类名访问即可
}                          
bubuko.com,布布扣

反射main方法:

  

bubuko.com,布布扣
    @Test
    public void test7() throws Exception{
        Class clazz = Class.forName("peng.Demo.Person1");
        Person1 p = (Person1) clazz.newInstance();
        Method method = clazz.getMethod("main", String[].class);
//        method.invoke(p, (Object)new String[]{"1","2"});
        //这样也行
        method.invoke(p, new Object[]{new String[]{"1","2"}});
    }
bubuko.com,布布扣

为什么要这么写?

  在JDK1.4时,invoke()方法时这样的    invoke(Object obj,Object[] os);

  当调用的方法有多个参数时,将多个参数写在一个数组中送给invoke,在调用方法时,会将该数组的参数打散,根据这些数组参数找到相对应的方法执行

  

  在JDK1.5后,可变参数出现了,在使用invoke时,可以直接写多个参数   invoke(Object obj ,Obj...o);

  为了向下兼容,如果你传递给invoke不是可变参数而是一个Object数组的话,仍旧会按照JDK1.4那样将数组打散

  我们可以把数组强转为Object,这样就不会打散了,也可以在外面再嵌套一个数组,这样打散后里面的数组就能正常成为参数正常进行调用了

注意:只有Object数组才会打散,基本数据类型数组是不会的

Java反射学习笔记,布布扣,bubuko.com

Java反射学习笔记

原文:http://www.cnblogs.com/ZePeng/p/3595253.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!