package com.appleyk.reflect;
public class Animal {
public String name ="Dog";
private int age =30 ;
//默认无参构造函数
public Animal(){
System.out.println("Animal");
}
//带参数的构造函数
public Animal(String name , int age){
System.out.println(name+","+age);
}
//公开 方法 返回类型和参数均有
public String sayName(String name){
return "Hello,"+name;
}
}
package com.appleyk.test;
public class ReflectTest {
public static void main(String args[]) throws Exception{
//do something
}
}
F:\Java\ReflectClass\bin\com\appleyk\reflect>javap -c Animal.class
Compiled from "Animal.java"
public class com.appleyk.reflect.Animal {
public java.lang.String name;
public com.appleyk.reflect.Animal();
Code:
0: aload_0
1: invokespecial #12 // Method java/lang/Object."":
()V
4: aload_0
5: ldc #14 // String Dog
7: putfield #16 // Field name:Ljava/lang/String;
10: aload_0
11: bipush 30
13: putfield #18 // Field age:I
16: getstatic #20 // Field java/lang/System.out:Ljava/
io/PrintStream;
19: ldc #26 // String Animal
21: invokevirtual #28 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
24: return
public com.appleyk.reflect.Animal(java.lang.String, int);
Code:
0: aload_0
1: invokespecial #12 // Method java/lang/Object."":
()V
4: aload_0
5: ldc #14 // String Dog
7: putfield #16 // Field name:Ljava/lang/String;
10: aload_0
11: bipush 30
13: putfield #18 // Field age:I
16: getstatic #20 // Field java/lang/System.out:Ljava/
io/PrintStream;
19: new #39 // class java/lang/StringBuilder
22: dup
23: aload_1
24: invokestatic #41 // Method java/lang/String.valueOf:(
Ljava/lang/Object;)Ljava/lang/String;
27: invokespecial #47 // Method java/lang/StringBuilder."<
init>":(Ljava/lang/String;)V
30: ldc #49 // String ,
32: invokevirtual #51 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
35: iload_2
36: invokevirtual #55 // Method java/lang/StringBuilder.ap
pend:(I)Ljava/lang/StringBuilder;
39: invokevirtual #58 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
42: invokevirtual #28 // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
45: return
public java.lang.String sayName(java.lang.String);
Code:
0: new #39 // class java/lang/StringBuilder
3: dup
4: ldc #64 // String Hello,
6: invokespecial #47 // Method java/lang/StringBuilder."<
init>":(Ljava/lang/String;)V
9: aload_1
10: invokevirtual #51 // Method java/lang/StringBuilder.ap
pend:(Ljava/lang/String;)Ljava/lang/StringBuilder;
13: invokevirtual #58 // Method java/lang/StringBuilder.to
String:()Ljava/lang/String;
16: areturn
}
package com.appleyk.test;
import java.lang.reflect.Constructor;
import com.appleyk.reflect.Animal;
public class ReflectTest {
public static void main(String args[]) throws Exception{
//do something
//1、加载类 ,指定类的完全限定名:包名+类名
Class c1 = Class.forName("com.appleyk.reflect.Animal");
System.out.println(c1);//打印c1,发现值和字节码中的类的名称一样
//2、解刨(反射)类c1的公开构造函数,且参数为null
Constructor ctor1= c1.getConstructor();
//3、构造函数的用途,就是创建类的对象(实例)的
//除了私有构造函数外(单列模式,禁止通过构造函数创建类的实例,保证一个类只有一个实例)
//ctor1.newInstance()默认生成一个Object对象,我们需要转化成我们要的Animal类对象
// Object a1 = ctor1.newInstance();
Animal a1 = (Animal)ctor1.newInstance();
//4、证明一下a1确实是Animal的实例,我们通过访问类中的变量来证明
System.out.println(a1.name);
}
}
package com.appleyk.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import com.appleyk.reflect.Animal;
public class ReflectTest {
public static void main(String args[]) throws Exception {
// do something
System.out.println("A(无参构造函数)--加载类、反射类的构造函数、利用构造函数new一个Animal实例instance--");
// 1、加载类 ,指定类的完全限定名:包名+类名
Class c1 = Class.forName("com.appleyk.reflect.Animal");
System.out.println(c1);// 打印c1,发现值和字节码中的类的名称一样
// 2.a、解刨(反射)类c1的公开构造函数,且参数为null
Constructor ctor1 = c1.getConstructor();
// 3、构造函数的用途,就是创建类的对象(实例)的
// 除了私有构造函数外(单列模式,禁止通过构造函数创建类的实例,保证一个类只有一个实例)
// ctor1.newInstance()默认生成一个Object对象,我们需要转化成我们要的Animal类对象
// Object a1 = ctor1.newInstance();
Animal a1 = (Animal) ctor1.newInstance();
// 4、证明一下a1确实是Animal的实例,我们通过访问类中的变量来证明
System.out.println(a1.name);
System.out.println("A(有参构造函数)--加载类、反射类的构造函数、利用构造函数new一个Animal实例instance--");
// 2.b、 解刨(反射)类c1的公开构造函数,参数为string和int
Constructor ctor2 = c1.getConstructor(String.class, int.class);
Animal a2 = (Animal) ctor2.newInstance("Cat", 20);
System.out.println("B--获得本类中的所有的字段----------------------------");
// 5、获得类中的所有的字段 包括public、private和protected,不包括父类中申明的字段
Field[] fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("C--获得本类中的所有公有的字段,并获得指定对象的字段值-----");
// 6、获得类中的所有的公有字段
fields = c1.getFields();
for (Field field : fields) {
System.out.println(field + ", 字段值 = " + field.get(a1));
// 注意:私有变量值,无法通过field.get(a1)进行获取值
// 通过反射类中的字段name,修改name的值(注意,原值在类中name="Dog")
// 如果,字段名称等于"name",且字段类型为String,我们就修改字段的值,也就是类中变量name的值
if (field.getName() == "name" && field.getType().equals(String.class)) {
String name_new = (String) field.get(a1);// 记得转换一下类型
name_new = "哈士奇";// 重新给name赋值
field.set(a1, name_new);// 设置当前实例a1的name值,使修改后的值生效
}
}
System.out.println("利用反射出的字段,修改字段值,修改后的name = " + a1.name);
System.out.println("D--获取本类中的所有的方法--------------------");
// 7、获取本类中所有的方法 包括public、private和protected,不包括父类中申明的方法
Method[] methods = c1.getDeclaredMethods();
for (Method m : methods) {
System.out.println(m);// 我们在类Animal中只定义了一个public方法,sayName
}
System.out.println("E--获取本类中的所有的公有方法,包括父类中和实现接口中的所有public方法-----------");
// 8、获取类中所有公有方法,包括父类中的和实现接口中的所有public 方法
methods = c1.getMethods();
for (Method m : methods) {
System.out.println(m);// 我们在类Animal中只定义了一个public方法,sayName
}
System.out.println("F--根据方法名称和参数类型获取指定方法,并唤起方法:指定所属对象a1,并给对应参数赋值-----------");
// 9、唤起Method方法(执行) getMethod:第一个参数是方法名,后面跟方法参数的类
Method sayName = c1.getMethod("sayName", String.class);
System.out.println(sayName.invoke(a1, "Tom"));
}
}
//解析 元素的id属性得到该字符串值为"sqlSessionFactory"
String idStr = "sqlSessionFactory";
//解析 元素的class属性得到该字符串值为"org.mybatis.spring.SqlSessionFactoryBean"
String classStr = "org.mybatis.spring.SqlSessionFactoryBean";
//利用反射知识,通过classStr获取Class类对象
Class cls = Class.forName(classStr);
//实例化对象
Object obj = cls.newInstance();
//container表示Spring容器
container.put(idStr, obj);
//当一个类里面需要用另一类的对象时,我们继续下面的操作
//解析 元素的name属性得到该字符串值为“dataSource”
String nameStr = "dataSource";
//解析 元素的ref属性得到该字符串值为“dataSource”
String refStr = "dataSource";
//生成将要调用setter方法名
String setterName = "set" + nameStr.substring(0, 1).toUpperCase()
+ nameStr.substring(1);
//获取spring容器中名为refStr的Bean,该Bean将会作为传入参数
Object paramBean = container.get(refStr);
//获取setter方法的Method类,此处的cls是刚才反射代码得到的Class对象
Method setter = cls.getMethod(setterName, paramBean.getClass());
//调用invoke()方法,此处的obj是刚才反射代码得到的Object对象
setter.invoke(obj, paramBean);