java反射机制学习

                         Java反射技术

反射的核心思想

所谓的反射就是将一个类中的各个成员映射成相对应的JAVA类型

反射核心思想图

 java反射机制学习

反射的目的

1.传递一个实体类---à装换成Map

2.将Map转换成一个实体类

 

1.    获取字节码文件的三种方式

a)     Java类的组成部分

1.     每个类都有一个package

2.     每个类都有一个类名

3.     会有构造方法

4.     类中可以有属性

5.     可以有普通的方法

b)    Class类是反射的根基(是作者为我们提供一个可以描述JAVA文件的类,Class类型的对象可以代表某一个类的字节码文件)

 

2.    如何获取一个类的字节码文件(也就是Class对象)

1)      通过某一个类类名.class

publicclass TestDome {

  @Test

  publicvoid test(){

     //此处的c1代表的是User这个类的字节码文件,此处的Class是一个数据类型,c1就是这个类型的对象

     Class c1=User.class;

     Class c2=Tree.class;

     System.out.print(c1);

     System.out.print(c2);

  }

2)      通过某一个Class.forName(“某个类的全路径”);

Class c3=Class.forName("com.fanshe.test.Tree");

3)      通过某一个对象名.getClass();

User user=new User();

Class c4=user.getClass();

3.    通过反射创建对象

4.     创建对象时一定会调用构造方法,因此需要通过反射先获取字节码文件(反射的根基),然后通过字节码来获取指定的构造方法-------再通过构造器创建对象

获取所有的构造方法:(获取某一个类中所有的构造方法【getConstructors()】)

@Test

  publicvoid test1() throws ClassNotFoundException{//异常是字节码类文件找不到异常

     //springIOC:控制反转--就是将某一个类的对象创建过程交给spring容器

     //<bean id="xx" calss="com.fanshe.test.Tree"></bean>

     //1.获取字节码文件

     Class calssuser=Class.forName("com.fanshe.test.User");

     //所谓的反射就是将一个类中的各个成员映射成相对应的java类型

     //2.需要创建一个对象(创建对象是一定要调用构造方法的)

     //调用User类中的无惨构造方法创建对象

     Constructor[] userconstors=calssuser.getConstructors();

     for (Constructor constructor : userconstors) {

       System.out.println(constructor);

     }

}

获取指定的构造方法:(通过指定参数类型来获取某一具体的构造方法【getConstructors()】)

@Test

  publicvoid test2() throws Exception{

     //通过字节码文件获取指定构造方法--无参数

     Class calssuser=Class.forName("com.fanshe.test.User");

     Constructor constructor1=calssuser.getConstructor();

     System.out.println(constructor1);

     //通过字节码文件获取指定构造方法--有参数

     Constructor constructor2=calssuser.getConstructor(String.class,int.class);

     System.out.println(constructor2);

}

通过无惨构造函数创建对象

@Test

  publicvoid test3() throws Exception{

     //通过字节码文件获取指定构造方法--无参数

     Class calssuser=Class.forName("com.fanshe.test.User");

     Constructor constructor1=calssuser.getConstructor();

     User user=(User) constructor1.newInstance();

     System.out.println(user);

}

4.反射的效率问题

反射的创建对象要比传统的创建对象方式效率低很多

5. 通过反射来获取某一实体类中属性字段

a)     通过反射获取publicprotected,默认访问修饰符修饰字段

 @Test

 publicvoid test() throws Exception{

   //1.创建一个对象

    Class userclass=User.class;

   User user=(User)userclass.getConstructor().newInstance();

    //2.获取user这个类中的属性字段

   Field[] field=userclass.getDeclaredFields();

    for (Field field2 : field) {

     System.out.println(field2);

   }

}

 

b) 通过反射获取属性字段的访问修饰符

@Test

publicvoid test2() throws Exception{

Class userclass=User2.class;

User2 user=(User2)userclass.getConstructor().newInstance();

Field field=userclass.getDeclaredField("age");

int mod=field.getModifiers();

System.out.print("字段的访问修饰符是"+mod);

/**

* --

* 0--代表的是默认的

* 1--代表的是public

* 2--代表的是private

* 4--代表的是protected

*/

}

c)    通过暴力反射获取private修饰过的属性字段的值(私有的)

/**

* 通过暴力反射获取属性字段的值

* @throws Exception

*/

@Test

publicvoid test3() throws Exception{

Class userclass=User2.class;

User2 user=(User2)userclass.getConstructor().newInstance();

Field field=userclass.getDeclaredField("age");

field.setAccessible(true);//设置访问修饰符的可见性(暴力反射)

Object obj=field.get(user);

System.out.println(obj);

  }

d)   通过反射修改指定属性字段的值

@Test

  publicvoid test3() throws Exception {

     Class userclass = User2.class;

     User2 user = (User2) userclass.getConstructor().newInstance();

     Field field = userclass.getDeclaredField("age");

     field.setAccessible(true);// 设置访问修饰符的可见性

     Object obj = field.get(user);// get方法获取指定属性字段的值

     System.out.println("被修改前的值是"+obj);

     field.set(user, 222);//set方法修改指定属性字段的值(-user类中要有toString方法)

     System.out.println("被修改后的值" + user);

  }

 

通过反射调用方法

1.     通过反射获取所有的方法

@Test

  publicvoid test4() throws Exception{

    //通过反射调用方法

    Class userclass = User2.class;

    Method[] mh=userclass.getMethods();

    for (Method method : mh) {

    System.out.println(method); 

    }

通过反射获取指定的方法

@Test

  publicvoid test5() throws Exception{

     //通过反射调用指定的方法

     Class<User2> userclass = User2.class;

     User2 user = (User2) userclass.getConstructor().newInstance();

     //获取user类中的tostring方法--无参

     Method mo=userclass.getMethod("tostring");

     mo.invoke(user);

    

  }

  @Test

  publicvoid test6() throws Exception{

     //通过反射调用指定的方法

     Class<User2> userclass = User2.class;

     User2 user = (User2) userclass.getConstructor().newInstance();

     //获取user类中的tostring方法--有参

     Method mo=userclass.getMethod("tostring",int.class);

     mo.invoke(user,26);

    

  }

打包JAR包的方法—鼠标右键单击项目—Export—java—JAR file—选择保存的位置—最后OK(apache提供一个jar工具,将map装换成实体类,将实体类装换成map-工具名为commons-beanutils.jar)