反射的三种方式:
Class colLoder = col.getClass(); //有一个对象的时候用
Class colLoder = Class.forName("com.softeem.bean.College"); //知道包名和类名的时候用
Class colLoder = College.class; //有个类名的时候用
College col = new College();
Class colLoder = col.getClass();
Method m = colLoder.getMethod(setN, String.class); //创建一个set方法。括号里面的第一个参数表示这个名字的set方法,第二个参数表示的是这个名字set方法的参数的类型
m.invoke(col, att1Value);à调用执行这个方法。括号里面的第一个参数表示调用这个方法的对象;第二个参数表示传到这个set方法中的值,这里把att1Value传到这个set方法里面去
// 1.先写一个Student类,
例子代码:
package com.softtem.ppt06reflex;
package com.softtem.ppt06reflex;
public class Student {
public String name;
private String sex;
public int age;
private int grade;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
}
// 2.写一个Test类,在这个类里面用反射机制把Student类中的字段,属性,方法等找出来,并给Student类中的set方法赋值,把其中的get方法值取出来
package com.softtem.ppt06reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
try {
// String str = "com.softeem.ppt06reflex.Student";
// // 通过jdk中已经封装好的类“Class”中的forName()方法加载类
// Class c = Class.forName(str);
// // 通过Class类中的newInstance();创建对象
// Object o = c.newInstance();// 这里的o就是上面那个字符串的对象
// Student s = (Student) o;
String str = "com.softtem.ppt06reflex.Student";
Student s = (Student) Class.forName(str).newInstance();
// 我们可以通过以下三种方式获得一个类的描述:
// Class c1 = s.getClass();//对象调用getClass()方法
// Class c2 = Student.class;//类名调用Class属性
Class c = Class.forName(str);// 反射加载
System.out.println(c);
// 通过Class对象调用getConstrutor()方法,可以获取这个类这类中的所有构造器
Constructor[] cons = c.getConstructors();
System.out.println(cons.length);
Field[] fields = c.getDeclaredFields();// 获取Student类中所有的字段,包括公有的和私有的,从父类继承的属性除外
Field[] fields2 = c.getFields();// 获取Student类中所有公有的字段
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
// Field f2 = fields2[i];
String fieldName = f.getName();
System.out.println(fieldName);
// String fieldName2 = f2.getName();
// System.out.println(fieldName2);
}
Method[] methodes = c.getMethods();
for (int i = 0; i < methodes.length; i++) {
Method m = methodes[i];
// 获得方法的名字
String methodName = m.getName();
// 给name赋值
if ("setName".equals(methodName)) {
Object[] obj = { new String("haha") };
m.invoke(s, obj);
}
// 给age赋值
if ("setAge".equals(methodName)) {
Object[] obj = { new Integer(15) };
m.invoke(s, obj);
}
// 给sex赋值
if ("setSex".equals(methodName)) {
Object[] obj = { new String("女") };
m.invoke(s, obj);
}
// System.out.println(methodName+"方法");
// //取到方法的返回类型
// Class rt = m.getReturnType();
// System.out.println(methodName+"方法的返回类型是:"+rt+"\r");
// //获取参数类型
// Class[] pts = m.getParameterTypes();
// System.out.print(methodName+"方法的参数的类型是:");
// for (int j = 0; j < pts.length; j++) {
// System.out.println("---"+pts[j]);
// }
}
for (int i = 0; i < methodes.length; i++) {
Method m1 = methodes[i];
String mn = m1.getName();
// 只要方法的名字是以”get“开头的就执行if里面的代码
if (mn.startsWith("get")) {
Object obj = m1.invoke(s, null);
System.out.println(obj);
}
}
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println(s.getSex());
} catch (Exception e) {
{
e.printStackTrace();
}
}
}
// 通过反射创建一个对象
package com.softtem.ppt06reflex;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test2 {
public static void main(String[] args) {
try {
String str = "com.softtem.ppt06reflex.Student";
// 通过反射创建一个Student对象
Class c = Class.forName(str);
Student s = (Student) Class.forName(str).newInstance();
// 获取Student中的所有自定义字段
Field[] fields = c.getDeclaredFields();
// 获取Student中的所有方法
Method[] methods = c.getDeclaredMethods();
// 给每一个字段赋值:遍历每一个字段,依次调用每一个字段的set方法
for (int i = 0; i < fields.length; i++) {
Field f = fields[i];
// 取到当前字段的名字
String fName = f.getName();
// 根据字段名确定其对应的set方法的名字:字段名首字母改为大写,在前面加上set
String mappingName = "set"
+ fName.substring(0, 1).toUpperCase()
+ fName.substring(1);
System.out.println(fName + "---" + mappingName);
// 根据需要的方法名和参数名类型,获得对应的set方法
Method m = c.getMethod(mappingName, f.getType());
System.out.println("获得的方法是:" + m.getName());
if ("java.lang.String".equals(f.getType().toString())) {
System.out.println("当前方法需要String");
Object[] obj = { "abc" };
m.invoke(s, obj);
} else if ("int".equals(f.getType().toString())) {
System.out.println("当前方法需要int");
Object[] obj = { 15 };
m.invoke(s, obj);
}
// 获取当前字段对应的get方法名字
String mappingGet = "get"
+ fName.substring(0, 1).toUpperCase().substring(1);
Method gm = c.getMethod(mappingName, null);
Object ooo = gm.invoke(s, null);
System.out.println(ooo);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}