目录
一.什么是Java反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能称为java语言的反射机制。
什么时候用到反射机制呢?
在仅知道“包名+类名”的情况下使用。
Java反射的作用:动态获取类的信息。
二.Class类
● 一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被使用时都会创建一个Class对象。
● Class类是Java反射机制的基础,通过Class类,可以得到一个类的基本信息。
获得
Class
的三种方法
要使用Class类的方法,必须先获得该类的Class类的实例,获得Class类实例的常用方法有如下三种:
● Object类中的getClass方法:适用于通过对象获得Class实例的情况 //已知类的对象时● 类名.class方式:适用于通过类名获得Class实例的情况 //知道类名的情况下● Class类的静态方法 forName(String name) //知道包名+类名的情况下
示例如下:
package com.ffyc.JavaReflect;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
//Java反射机制
//以前使用类,一致类名,new创建对象,调用对象成员
//User user=new User()
//user.方法
// 在使用Java反射机制时,只知道(类+包名)
String classname="com.ffyc.JavaReflect.User";
//如何获取类的信息 可以通过Class类来获得类中的信息
//如何获得类的Class对象
//方式一:
Class class1=Class.forName(classname);
System.out.println(class1);
//方式二:
//动态操作class信息
Class class2= User.class;
System.out.println(class2==class1);
//方式三:
User user=new User();
Class class3=user.getClass();
System.out.println(class3==class1);
}
}
三.Constructor类
Constructor实例通过Class实例获得,Class类中定义了如下方法:
● Constructor<T> getConstructor(Class... parameterTypes)通过指定参数类型,返回构造方法实例
Constructor类可以通过getXXX方法获得构造方法的基本信息.● getName:返回构造方法的名字除了获得构造方法的基本信息,还可以创建实例● newInstance(Object... initargs) :创建实例
注意:Constructor只能获得公共类的构造方法!!!
示例如下:
package com.ffyc.JavaReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
String classname="com.ffyc.JavaReflect.User";
//String classname="com.ffyc.JavaReflect.Car";
/*
Java中创建对象的方式:
1.new
2.反序列化
3.反射机制(两种,类对象创建,类对象的构造方法创建)
4.对象克隆
*/
//通过类名,获得到类的class对象
Class aClass=Class.forName(classname);
//2.通过类的Class对象,创建对象
Object object = aClass.newInstance();
System.out.println(object);
//获得类中的构造方法,通过构造方法api中的方法创建对象
Constructor constructor1 = aClass.getConstructor(); //获得指定的公共构造方法
Object object1 = constructor1.newInstance(); //创建对象
Constructor constructor2 = aClass.getConstructor(String.class,String.class);
Object object2 = constructor2.newInstance("张三","111");
System.out.println(object1);
System.out.println(object2);
Constructor[] constructors= aClass.getConstructors(); //获得所有的公共的构造方法
System.out.println(constructors.length);
//虽然可以获得私有构造方法,但是一般不建议操作私有成员,因为打破了封装性
aClass.getDeclaredConstructor(); //获得类中任意的构造方法,包含私有的
System.out.println(aClass.getDeclaredConstructors().length);
}
}
四.获得Field实例
● 获得Field实例,都是通过Class中的方法实现
● public Field getField(String name)通过指定Field名字,返回Field实例.注意Field的访问权限
通过反射机制,还可以对类中的成员属性进行操作:
Field[] fields = aClass.getDeclaredFields();
这里拿到的就是属性的一个集合。因为属性是不可以直接使用的,属性单独拿出来只是一个抽象概念,必须需要一个对象去对对象中的属性进行操作(赋值等),所以在其中必然是存在一个方法可以将其属性依托于某个对象来使用的。方法如下:
field.set(Object object,Object value);
//这里第一个变量就是属性所寄存的对象名,第二个变量就是变量的值
示例如下:
package com.ffyc.JavaReflect;
import java.lang.reflect.Field;
import java.util.HashMap;
public class Test3 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String classname="com.ffyc.JavaReflect.User";
//String classname="com.ffyc.JavaReflect.Car";
//通过类名,获得到类的class对象
Class aclass=Class.forName(classname);
//2.通过类的Class对象,创建对象
Object object = aclass.newInstance();
//模拟从数据库查到的数据
HashMap<String,String> map=new HashMap<>();
map.put("account","zhangsan");
map.put("password","111");
Field[] declaredFields = aclass.getDeclaredFields(); //获得类中所有的成员变量
for(Field field:declaredFields){
field.setAccessible(true); //允许访问操作私有属性,不建议
field.set(object,map.get(field.getName())); //get(field.getName())得到成员变量名
}
System.out.println(object);
}
}
Field类的作用
●
Field类将类的属性进行封装,可以获得属性的基本信息、属性的值,也可以对属性进行赋值.
●
getName:返回属性的名字
●
set:设置属性值
五.获得Method实例
●
Method实例都是通过Class类的方法获得
●
Method getMethod(String name, Class... parameterTypes) : 通过指定方法名,参数类型,返回一个Method实例.
Method类的作用
Method类将类中的方法进行封装,可以动态获得方法的信息,例如:
●
getName:获得方法名字
●
getParameterTypes:获得方法参数类型
●
除了动态获得方法信息外,Method还能动态调用某一个对象的具体方法
●
invoke(Object obj, Object... args) :使用obj调用该方法,参数为args
Method method = aclass.getMethod("eat",String.class); //使用有参构造方法eat()
//调用访问eat()方法
method.invoke(object,"111");//invoke中的参数不能独立存在,意思是:必须要有对象存在(这里是object),"111"为参数的值
结果如图所示:
六.自定义java对象转json工具类
package com.ffyc.JavaReflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class JsonUtil {
public static String ObjectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Class aclass5=object.getClass();
String json="{";
//获得类中所有的属性,指的是变量名
Field[] declaredFields = aclass5.getDeclaredFields();
for(Field field:declaredFields){
//生成属性get方法名字
String getmothod="get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
//获得方法对象
Method method = aclass5.getMethod(getmothod);
//把属性名和值拼接成键值
Object value = method.invoke(object);
json+=field.getName()+":"+value+",";
}
json=json.substring(0,json.length()-1);//去掉末尾的逗号
json+="}";
return json;//{属性:值,属性:值}
}
public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
User user=new User();
user.setAccount("张三");
user.setPassword("111");
Car car=new Car();
car.setName("特斯拉");
car.setColor("黑色");
System.out.println(JsonUtil.ObjectToJson(user));
System.out.println(JsonUtil.ObjectToJson(car));
}
}
上述代码就是用反射机制的相关知识自定义的java对象转json工具类,希望可以帮助到大家。
今天的分享到这里就结束了,制作不易,兄弟姐妹们,记得一键三连哦!!!