package net.csdn.blog.wdd9527.week05.day03.test01;
//获取未知类里面的内容(没有提及的参考获取)
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo {
public static void main(String[] args) {
//test01();//拿对象
//test02();//拿属性
//test03();//拿构造方法
test04();//拿方法
}
//拿对象
public static void test01() {
//方法1.使用对象.class(); 不推荐使用
Worker w = new Worker();
Class<? extends Worker> c1 = w.getClass();
System.out.println(c1);
//方法2.使用Class类的静态方法,forName();参数为类的全限定路径名, 推荐使用
try {
Class<?> c2 =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
System.out.println(c2);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//方法3.使用类的.class语法,不推荐使用
Class<?> c3 = Worker.class;
System.out.println(c3);
//方法4.针对包装类,有一个TYPE语法,用的少,
//Integer i = 22;
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4);
}
//拿属性 一般不做拿属性的操作 了解了解把
public static void test02() {
try {
//首先要拿到对象
Class<?> c =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
//.getFields() 拿到所有共有的方法
Field[] fields = c.getFields();
for (Field field : fields) {
//.toString()与.toGenericString() 后者更详细,推荐用
System.out.println(field.toGenericString());
}
//.getDeclaredFields() 拿到所有的方法
Field[] declaredFields = c.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field.toGenericString());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//拿构造方法
public static void test03() {
try {
Class<?> c =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
//.getConstructors() 拿到所有共有的构造方法
Constructor<?>[] constructors = c.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.toGenericString());
}
//.getDeclaredConstructors() 拿到所有构造方法
Constructor<?>[] declaredConstructors = c.getDeclaredConstructors();
for (Constructor<?> constructor : declaredConstructors) {
System.out.println(constructor.toGenericString());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//拿方法
public static void test04() {
try {
Class<?> c =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
//.getMethods()
// 拿方法有点特殊,这个是拿到所有共有的方法(包括从父类继承来的方法,隐藏的方法)
/*Method[] methods = c.getMethods();
for (Method method : methods) {
System.out.println(method.toGenericString());
}
*/
//.getDeclaredMethods() 拿到本类的所有方法,包括私有的,仅限本类
Method[] declaredMethods = c.getDeclaredMethods();
for (Method method : declaredMethods) {
System.out.println(method.toGenericString());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package net.csdn.blog.wdd9527.week05.day03.test01;
import java.lang.reflect.Constructor;
//动态初始化对象
public class Demo02 {
public static void main(String[] args) {
//Worker w = new Worker(); 常用的初始化对象的方法
try {
/**
* 1.首先要获取要初始化的对象
* 2.然后用这个对象调用.newInstance()方法,初始化一个无参的对象。
*/
//无参构造方法初始化对象
Class<?> c =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
Object obj = c.newInstance();
//初始化成功之后,也可以向下转型,然后对该对象类的内容进行相关操作
if (obj instanceof Worker) {
Worker w = (Worker) obj;
w.setName("王二麻子");
w.setAge(22);
}
System.out.println(obj.toString()); //获取无参,即没有赋值,全是null
/**
* 1.首先要获得要初始化的对象
* 2.然后这个对象调用.getConstructor(参数列表)方法,获得带参的构造方法
* 3.然后用这个带参的构造方法调用 .newInstance(参数列表),进行初始化对象
* 注意:1.获取构造方法的时候,参数列表要和此类拥有的构造方法的参数列表相对应
* 2.用.getConstructor(参数列表)获取构造方法,参数列表要用:类型.class相对应
*/
//有参构造方法的初始化
Class<?> c1 =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
//parameterTypes 参数类型/形参列表(包括类型和个数)
//获取带参数的构造函数
Constructor<?> constructor = c1.getConstructor(String.class);
//用获取的构造函数进行初始化
Object newInstance = constructor.newInstance("张三");
//初始化成功之后,也可以向下转型,然后对该对象类的内容进行相关操作
if (newInstance instanceof Worker) {
Worker w = (Worker) newInstance;
w.setAge(18);
w.setSalary(88);
w.work();
}
System.out.println(newInstance);
/**
* 使用Method的invoke方法执行方法,而不是通过对象(重点)
*/
//获得要初始化的对象
Class<?> c2 =
Class.forName("net.csdn.blog.wdd9527.week05.day03.test01.Worker");
//获得要初始化的对象的构造函数
Constructor<?> constructor2 = c2.getConstructor();
//初始化对象
Object newInstance2 = constructor2.newInstance();
//获取这个对象所在类中将要用到的方法 参数为方法名和需要的形参
Method method = c2.getMethod("setName", String.class);
//用获得的这个方法调用.invoke() 传入要操作的对象和这个方法需要的形参
Object invoke = method.invoke(newInstance2, "李四");
Method method2 = c2.getMethod("setAge", Integer.class);
method2.invoke(newInstance2, 33);
System.out.println(newInstance2.toString());
System.out.println(method);
System.out.println(invoke);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
Worker [name=王二麻子, age=22, salary=null]
张三正在努力干活....
Worker [name=张三, age=18, salary=88]
Worker [name=李四, age=33, salary=null]
public void net.csdn.blog.wdd9527.week05.day03.test01.Worker.setName(java.lang.String)
null
package net.csdn.blog.wdd9527.week05.day03.test01;
//不论类在哪里,只要路径对了就可以(同一个项目下)
import java.lang.reflect.Constructor;
import net.csdn.blog.wdd9527.week01.day01.Teacher;
public class Demo03 {
public static void main(String[] args) {
try {
Class<?> c = Class.forName("net.csdn.blog.wdd9527.week01.day01.Teacher");
Constructor<?>[] constructors = c.getConstructors();
Constructor<?> constructor2 = c.getConstructor();
Object obj = constructor2.newInstance();
if (obj instanceof Teacher) {
Teacher t = (Teacher) obj;
t.setName("苍老师");
}
System.out.println(obj);
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
输出结果:
Teacher [name=苍老师, course=null]
public net.csdn.blog.wdd9527.week01.day01.Teacher(java.lang.String,java.lang.String)
public net.csdn.blog.wdd9527.week01.day01.Teacher()
package net.csdn.blog.wdd9527.week05.day03.test02;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Set;
public class Main {
public static void main(String[] args) {
/**
* 1.创建两个map集合,分别保存Student和Worker的信息
* 2.把信息分别赋值给Student和Worker对象
* 3.把第二步抽象成一个方法(不然再添加呢?)
*/
HashMap<Object, Object> map1 = new HashMap<>();
map1.put("name", "张三");
map1.put("age", 22);
map1.put("sex", '男');
map1.put("grade", 5);
System.out.println(map1);
HashMap<Object, Object> map2 = new HashMap<>();
map2.put("name", "李四");
map2.put("age", 21);
map2.put("salary", 9999);
System.out.println(map2);
//map1的
/*Student s = new Student();
System.out.println(s.getClass());*/
try {
Object setObj = setObj(map1,
"net.csdn.blog.wdd9527.week05.day03.test02.Student");
System.out.println(setObj);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//map2的
/*Worker s1 = new Worker();
System.out.println(s1.getClass());*/
try {
Object setObj2 =
setObj(map2,"net.csdn.blog.wdd9527.week05.day03.test02.Worker");
System.out.println(setObj2);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*Student s = new Student();
s.setName((String)map1.get("name"));
s.setAge((int)map1.get("age"));
s.setSex((char)map1.get("sex"));
s.setGrade((Integer)map1.get("grade"));
System.out.println(s.toString());
Worker s1 = new Worker();
s1.setName((String)map2.get("name"));
s1.setAge((int)map2.get("age"));
s1.setSalary((int)map2.get("salary"));
System.out.println(s1.toString());*/
}
public static Object setObj(HashMap<Object, Object> map,String className) throws Exception {
Class<?> forName = Class.forName(className); //获取形参所代表类的对象
Object newInstance = forName.newInstance(); //初始化这个对象
Method[] methods = forName.getMethods(); //获取类中的所有方法,待会筛选出需要的set方法
Set<Object> keySet = map.keySet(); //遍历键,从而得到需要的值,达到对象的初始化
/**
* 分别要循环形参所代表类的所有方法和形参传来的map集合的键,
* 从而获得所需要的set方法和键所对应的值,
* 从而达到对象的初始化
* setName-->name
* setAge-->age
* setSex-->sex
* setGrade-->grade
*/
for (Object key : keySet) {
if (key instanceof String) { //讲key值转换为String类型,方便比较
String k = (String) key;
for (Method m : methods) {
//只需要setXXX的方法,所以首先筛选出以set开头的方法,然后再判断键
if (m.getName().startsWith("set") && k.equalsIgnoreCase(m.getName().substring(3))) {
m.invoke(newInstance, map.get(k)); //方法.invoke(对象,方法所对应的形参)
}
}
}
//System.out.println(key + " " + map.get(key));
}
return newInstance;
}
}