0
点赞
收藏
分享

微信扫一扫

Javaweb中提到的反射浅析(附源码)


反射:一个jdk5.0的新特性,高级运用。在后期的框架中,这个是一大重点,现在估计我们都不会太多的接触他的。但是为了后面的铺垫,我想还是先了解一下:

    

    先构造一个类,然后我们用反射来获取,调用里面的方法,属性

package com.changeyd.test09;


public class Person {
// 属性
private String name;
private String id;


// 没有参数的构造方法
public Person() {
}


public Person(String name, String id) {
super();
this.name = name;
this.id = id;
}


public String getName() {
return name;
}


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


public String getId() {
return id;
}


public void setId(String id) {
this.id = id;
}}


好了,创建好类了,就可以构造一个Test来获取它的内容了:

    哦。。对对对,在运用前,先得了解一下反射的基本原理:


一:反射的原理
*应用在一些通用性比较高的代码中
*在后期中的框架中,大多数都是使用反射来实现的


*在框架开发中,都是基于配置文件开发
**在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行


*类中的所有内容:属性、没有参数的构造方法,有参数的构造方法、普通方法


**反射的原理:
*首先需要把java文件保存到本地硬盘  .java
*编译java文件,成 .class文件
*使用jvm,把class文件通过类加载加载到内存中
*万事万物皆对象,class文件到内存中使用Class类表示


*当使用反射时候,首先需要获取到Class类,得到这个类之后,就可以得到clss文件里面的所有内容了
-包含属性  构造方法 普通方法
*属性通过一个类:Filed
*构造方法通过一个类:Constructor

*普通方法通过一个类:Method


二:现在就可以获取第一步,无参方法

使用反射操作类里面的无参数的构造方法

*首先获取到Class类
// 获取class类
Class class1 = Person.class;
Class class2 = new Person().getClass();
Class class3 = Class.forName("com.changeyd.test09.Person");
*比如:对一个类型进行实例化,可以new,如果不使用new,如何获取?
//得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
//得到Person类的实例
Person person = (Person) class1.newInstance();
-代码:
//操作无参数的构造方法
@Test
public void test1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{
//得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
//得到Person类的实例
Person person = (Person) class1.newInstance();
//设置值
person.setName("Wangji");
System.out.println(person.getName()); }


三:使用反射操作有参数的构造方法

四:使用反射来操作属性
* @Test

//操作有参数的构造方法
@Test
public void test2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException,
IllegalAccessException, IllegalArgumentException, InvocationTargetException {
// 得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");
// 使用有参数的构造方法
// class1.getConstructors();//获取所有的构造方法
Constructor cs = class1.getConstructor(String.class, String.class);
// 通过有参数的构造方法设置值
// 通过有参数的构造方法来创建Person实例
Person person = (Person) cs.newInstance("lisi", "100");
System.out.println(person.getId() + " " + person.getName()); }

五:使用泛型来操作普通方法
*使用Method来表示普通方法

public void test3() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
SecurityException, InstantiationException {
try {
// 得到class类
Class class1 = Class.forName("com.changeyd.test09.Person");


// 得到name属性
// class1.getDeclaredFields();//表示得到所有的属性
// 得到Person类的实例
Person person = (Person) class1.newInstance();
//通过这个方法得到属性,参数是属性的名称
Field field = class1.getDeclaredField("name");


//操作的是私有的属性,不让操作,需要设置可以操作私有属性setAccessible(true),可以操作私有属性
field.setAccessible(true);

// 设置name值 set方法,两个参数:第一个参数类的实例,第二个参数是设置的值
field.set(person, "wangwu");// 相当于在p.name = "wangwu";
System.out.println(field.get(person)); // 相当于p.name;


} catch (ClassNotFoundException e) {
e.printStackTrace();
} }

*代码
// 普通方法,比如操作 setName
@Test
public void test4() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
NoSuchMethodException, SecurityException, InstantiationException, ClassNotFoundException {
// 得到Class类
Class class1 = Class.forName("com.changeyd.test09.Person");
// 得到Person的实例
Person person = (Person) class1.newInstance();
// 得到普通方法
// class1.getDeclaredFields();//得到所有的普通方法
//传递两个参数:第一个参数,方法名称;第二个参数,通过方法设置的值
Method method = class1.getDeclaredMethod("setName", String.class);
// 让setName方法执行,执行设置值
//使用invoke(person, "niuqi");传递两个参数;第一个参数,person实例;第二个参数,设置的值
//执行了invoke方法之后,相当于,执行了setName方法,同事通过这个方法设置了一个值是niuqi。
method.invoke(person, "niuqi");


System.out.println(person.getName()); }


在里面还需要一些注意的地方:

//如果操作的是私有的方法,需要设置值为true
method.setAccessible(true);



*当操作的方法是静态的方法时候,因为静态方法调用的方式是 类名.方法名,不需要类的实例
*使用反射操作静态方法的时候,也是不需要实例
*在invoke方法的第一个参数里面,写一个null

-method.invoke(null, "wangji");


对于反射中,原理很重要,先了解,但是对于反射,这些只是皮毛,在进入框架,才有具体的认识

举报

相关推荐

0 条评论