目录
1、当任何一个java类被加载到内存时,程序就会为其创建一个Class对象。
2、Class类是java反射机制的基础,通过Class类,可以得到任何一个java类的基本信息。
(1)使用Class类的类名调用Class类的静态方法-forName(String name)
(3)使用java类对象调用Object类中的getClass()方法的方式
八、模拟从数据库中查出数据并将查出来的数据保存到类对象的过程
2、获取java类中的所有的公共成员方法(包括从父类继承过来的)
3、获取java类 中的任一成员方法(不包括从父类中继承过来的)
4、获取java类中所有的成员方法(不包括从父类中继承过来的)
使用Construct对象调用newInstance()创建
一、java反射的引入
1、在学习java反射之前,我们使用java中的对象的流程是:
(1)定义一个类(2)使用这个类的类名创建一个类对象(3)使用创建好的这个类的类对象调用这个类对象中的属性和方法
2、这套对java中对象的使用流程适用于人,但是对于框架,如果框架只知道java类的地址,如何让框架实现对任意一个java类的使用?
框架通过java反射机制和一套该框架专属的处理程序,就可以让框架实现对任意一个java类的使用。
二、java反射的概念
java反射机制是指在程序运行状态下,对于任意一个类,都能够获取到这个类的的所有属性和方法;对于任意一个类对象,都能够调这个类对象的所有属性和方法;java语言的这种动态获取类信息以及动态创建类对象调用对象属性和方法的功能就是java语言的反射机制。
三、java反射的作用
动态获取任意一个类的信息
四、java反射API
java反射API将java中所有类的类型、属性、方法分别封装成了类。将java类的类型封装成了Class,将java类的构造方法封装成了Constructor,将java类的属性封装成了Field,将java类的成员方法封装成了Method。其中,Class在java.lang包中,Constructor、Field、Method都在java.lang.reflect包中。
五、Class类
1、当任何一个java类被加载到内存时,程序就会为其创建一个Class对象。
2、Class类是java反射机制的基础,通过Class类,可以得到任何一个java类的基本信息。
3、获取java类的Class类对象的四种方法:
(1)使用Class类的类名调用Class类的静态方法-forName(String name)
String s = "com.ffyc.javaflect.User";
// 使用类地址获取类的class对象
Class aClass = Class.forName(s);
(2)使用java类的类名调用class属性的方式
// 使用类名获取类的class对象
Class aClass1 = User.class;
(3)使用java类对象调用Object类中的getClass()方法的方式
Admin admin = new Admin();
// 使用对象名获取类的class对象
Class aClass2 = admin.getClass();
(4)使用Field对象调用getType()方法的方式
Class userClass = Class.forName("com.ffyc.javaflect.User");
Constructor constructor = userClass.getConstructor();
Object userObj = constructor.newInstance();
// 通过java类中的属性名获取该java类中的指定的公共属性,使用Field对象表示
Field idF = userClass.getField("phone");
// 获取idF表示的属性的属性类型
System.out.println(idF.getType());
六、使用Class对象获取java类中的构造方法
1、无参数的公共构造方法
Class userClass = Class.forName("com.ffyc.javaflect.User");
// 通过指定参数个数获取公共构造方法
// 无参数
// 用一个constructor对象表示所获取到的那个公共构造方法
Constructor constructor = userClass.getConstructor();
// 使用constructor对象创建对应的java类对象
Object obj = constructor.newInstance();
System.out.println(obj);
2、1个参数的公共构造方法
Class userClass = Class.forName("com.ffyc.javaflect.User");
// 1个参数
// 用一个constructor对象表示所获取到的那个公共构造方法
Constructor constructor = userClass.getConstructor(int.class);
// 使用constructor对象创建对应的java类对象
Object obj = constructor.newInstance(6);
System.out.println(obj);
3、2个参数的公共构造方法
Class userClass = Class.forName("com.ffyc.javaflect.User");
// 1个参数
// 用一个constructor对象表示所获取到的那个公共构造方法
Constructor constructor = userClass.getConstructor(int.class,String.class);
// 使用constructor对象创建对应的java类对象
Object obj = constructor.newInstance(6,"tom");
System.out.println(obj);
4、获取所有的公共构造方法
// 获取所有的公共构造方法
Constructor[] constructors = userClass.getConstructors();
System.out.println(constructors.length);
5、获取任意的构造方法(公有的和私有的均可)
// 获取任意的构造方法(公有的和私有的均可)
Constructor declaredConstructor = userClass.getDeclaredConstructor(int.class,String.class);
// 设置如果获取到的是私有的构造方法可以被访问
declaredConstructor.setAccessible(true);
Object obj = declaredConstructor.newInstance(66, "alice");
System.out.println(obj);
6、获取所有的构造方法(包括公有的和私有的)
// 获取所有的构造方法(包括所有公有的和私有的)
Constructor[] declaredConstructors = userClass.getDeclaredConstructors();
System.out.println(declaredConstructors.length);
七、使用Class对象获取java类中的属性
1、获取任一公共属性
Class userClass = Class.forName("com.ffyc.javaflect.User");
Constructor constructor = userClass.getConstructor();
Object userObj = constructor.newInstance();
// 通过java类中的属性名获取该java类中的指定的公共属性,使用Field对象表示
Field idF = userClass.getField("phone");
// 获取idF表示的属性的属性名
System.out.println(idF.getName());
// 获取idF表示的属性的属性值
System.out.println(idF.get(userObj));
// 获取idF表示的属性的属性类型
System.out.println(idF.getType());
2、获取所有公共属性
// 获取java类中所有的公共属性
Field[] fields = userClass.getFields();
System.out.println(fields.length);
3、获取任一属性
// 根据属性名获取java类中的任一属性
Field idF1 = userClass.getDeclaredField("id");
System.out.println(idF1.getName());
4、获取所有属性
// 获取java类中的所有属性
Field[] declaredFields = userClass.getDeclaredFields();
System.out.println(declaredFields.length);
八、模拟从数据库中查出数据并将查出来的数据保存到类对象的过程
// 1、保存从数据库中查出来的数据
HashMap<String,String> map = new HashMap<>();
map.put("account", "努力奔跑");
map.put("password", "12345");
Class userClass = Class.forName("com.ffyc.javaflect.Admin");
Constructor constructor = userClass.getConstructor();
// 2、创建类对象
Object userObj = constructor.newInstance();
// 3、将map中的数据放入类对象中
Field[] fs = userClass.getDeclaredFields();
for(Field f : fs){
// 设置如果f表示的是私有属性可以被访问
f.setAccessible(true);
f.set(userObj, map.get(f.getName()));
System.out.println(f.get(userObj));
}
九、使用Class对象获取java类中的成员方法
1、获取java类中的一个公共成员方法
Class userClass = Class.forName("com.ffyc.javaflect.User");
Object userObj = userClass.getConstructor().newInstance();
// 获取java类中的一个公共成员方法(通过方法名和方法的参数类型获取,使用Method表示)
Method printMethod = userClass.getMethod("print");// 无参
// 获取Method表示所表示的成员方法的名称
System.out.println(printMethod.getName());
// 通过Method调用获取到的成员方法
printMethod.invoke(userObj);
Method printMethod1 = userClass.getMethod("print",int.class);// 1个参数
// 通过Method调用获取到的成员方法
printMethod1.invoke(userObj,101);
Method printMethod2 = userClass.getMethod("print",int.class,String.class);// 2个参数
// 通过Method调用获取到的成员方法
printMethod2.invoke(userObj,202,"牛魔王");
2、获取java类中的所有的公共成员方法(包括从父类继承过来的)
// 获取java类的所有公共成员方法(包括从父类中继承过来的)
Method[] methods = userClass.getMethods();
System.out.println(methods.length);
for(Method m:methods){
System.out.println(m.getName());
}
3、获取java类 中的任一成员方法(不包括从父类中继承过来的)
// 获取java类的任一成员方法(不包括从父类中继承过来的)
Method showMethod = userClass.getDeclaredMethod("show");
// 设置Method对象如果表示的是私有方法那么该私有方法可以被访问
showMethod.setAccessible(true);
showMethod.invoke(userObj );
4、获取java类中所有的成员方法(不包括从父类中继承过来的)
// 获取java类中的所有方法(不包括从父类中继承过来的)
Method[] declaredMethods = userClass.getDeclaredMethods();
System.out.println(declaredMethods.length);
for(Method m:declaredMethods){
System.out.println(m.getName());
}
十、将任一java类对象转为json字符串
public class JsonUtil {
public static void main(String[] args) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
User user = new User(12,"jim");
String json = ObjectToJson(user);
System.out.println(json);
Admin admin = new Admin("好运来","1101");
json = ObjectToJson(admin);
System.out.println(json);
}
public static String ObjectToJson(Object obj) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class objClass = obj.getClass();
Field[] fields = objClass.getDeclaredFields();
String res = "{";
for(Field f: fields){
String get = "get"+String.valueOf(f.getName().charAt(0)).toUpperCase()+f.getName().substring(1);
System.out.println(get);
Method getMethod = objClass.getMethod(get);
res+=(f.getName()+":"+getMethod.invoke(obj)+",");
}
res = res.substring(0,res.length()-1);
res+="}";
return res;
}
}
十一、总结
1、获取java类的对象的三种方式:
(1)java类中的构造方法
(2)反序列化
(3)java语言的反射机制(可以细分为两种)
-
使用Class对象调用newInstance()创建
String s = "com.ffyc.javaflect.User";
Class aClass = Class.forName(s);
// 使用Class对象创建java类对象
Object obj =aClass.newInstance();
System.out.println(obj);
-
使用Construct对象调用newInstance()创建
Class userClass = Class.forName("com.ffyc.javaflect.User");
// 用一个constructor对象表示所获取到的那个公共构造方法
Constructor constructor = userClass.getConstructor();
// 使用constructor对象创建对应的java类对象
Object obj = constructor.newInstance();
System.out.println(obj);