Java 反射有什么魔法?
Java 反射在Java技术中有一个非常神奇的魔法,它可以做什么呢?
假设A.java 是一个黑盒子,我们只知道这个类的包名和类的名称,如何知道这个类中有哪些字段名称和字段类型以及方法名称和方法返回类型呢?
如图所示:
如果使用了我的这个工具类,我们只需要在主方法中这样调用:
public static void main(String[] args) {
List<String> fieldList=SmartObject.getClassFieldList(A.class,null);
for (String fieldName:fieldList
) {
System.out.println(fieldName);
}
}
然后就可以看到输出结果:
userId
username
password
哦,原来这个A类里面有三个成员属性,userId,username,password
但是这三个字段的类型是什么呢?
主方法这样调用
public static void main(String[] args) {
Map<String,String> classFieldMap=SmartObject.getClassFieldMap(A.class,null);
for (Map.Entry<String,String> classField:classFieldMap.entrySet()
) {
System.out.println("name="+classField.getKey()+",type="+classField.getValue());
}
}
输出结果:
name=password,type=java.lang.String
name=userId,type=java.lang.Long
name=username,type=java.lang.String
哦,原来是一个Long类型,两个String类型哈
如果不想要java.lang.String 前面的完整包名,只需要替换成这个方法即可
SmartObject.getClassSimpleFieldMap(A.class,null);
输出样例:
name=password,type=String
name=userId,type=Long
name=username,type=String
里面有哪些方法呢?
public static void main(String[] args) {
Map<String,String> classFieldMap=SmartObject.getClassMethodInfoMap(A.class);
for (Map.Entry<String,String> classField:classFieldMap.entrySet()
) {
System.out.println("method="+classField.getKey()+",method type="+classField.getValue());
}
}
输出结果
method=sayHello,method type=void
method=sayHi,method type=java.lang.String
如果不想要java.lang.String 前面的完整包名,只需要替换成这个方法即可
SmartObject.getClassSimpleMethodInfoMap(A.class);
输出样例:
name=sayHello,type=void
name=sayHi,type=String
哦,原来有两个方法哈
void sayHello();
String sayHi();
好了,现在我替你打开A.java这个黑盒子吧
import java.io.Serializable;
/**
* @author fairy
* @description
* @date 2019/5/4
*/
public class A implements Serializable {
private static final long serialVersionUID = -6581491259264879540L;
public Long userId;//用户Id
public String username;//账号
public String password;//密码
public void sayHello(){
System.out.println("Hello World");
}
public String sayHi(){
System.out.println("Hi World");
return "Hi World";
}
}
这就是反射的魔法,可以动态获取一个类中所有的成员字段信息和方法信息
更多用法
我们可以通过 反射动态获取一个类中所有的成员字段信息和方法信息
获取类信息
获取类字段信息
获取类中的方法信息
工具类
最后附上完整工具类代码:
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SmartObject {
/************************类信息***********************************************/
/**
* @dercription 获取类名(包括包名)
* @return String
* */
public static String getClassName(Class<?> object) {
return object.getName();
}
/**
* @dercription 获取类名(不包括包名)
* @return String
* */
public static String getClassSimpleName(Class<?> object) {
return object.getSimpleName();
}
/************************字段类信息***********************************************/
/**
* @dercription 获取一个类的成员属性名称列表
* @return List<String>
* */
public static List<String> getClassFieldList(Class<?> object,Boolean ignoreSerialVersionUID) {
//设置忽略序列化Id默认值
if(null==ignoreSerialVersionUID){
ignoreSerialVersionUID=true;
}
//推断类型
List<String> objectFiledList = new ArrayList<>();
//获取类信息
Class<?> classInfo;
try {
//加载类信息
classInfo = Class.forName(object.getName());
//使用反射获取该类的成员属性
Field[] fieldList = classInfo.getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
//忽略获取序列化ID
if(ignoreSerialVersionUID){
//如果字段是序列化字段,则忽略
if (!fieldList[i].getName().equals("serialVersionUID")) {
objectFiledList.add(fieldList[i].getName());
}
}else{
//序列化ID不忽略作为类的属性返回到结果中
objectFiledList.add(fieldList[i].getName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return objectFiledList;
}
/**
* @dercription 获取一个类的成员属性类型列表
* @return List<String>
* */
public static List<String> getClassFieldTypeList(Class<?> object,Boolean ignoreSerialVersionUID) {
//设置忽略序列化Id默认值
if(null==ignoreSerialVersionUID){
ignoreSerialVersionUID=true;
}
//推断类型
List<String> objectFiledList = new ArrayList<>();
//获取类信息
Class<?> classInfo;
try {
//加载类信息
classInfo = Class.forName(object.getName());
//使用反射获取该类的成员属性
Field[] fieldList = classInfo.getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
//忽略获取序列化ID
if(ignoreSerialVersionUID){
//如果字段是序列化字段,则忽略
if (!fieldList[i].getName().equals("serialVersionUID")) {
objectFiledList.add(fieldList[i].getType().getName());
}
}else{
//序列化ID不忽略作为类的属性返回到结果中
objectFiledList.add(fieldList[i].getType().getName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return objectFiledList;
}
public static List<String> getClassSimpleFieldTypeList(Class<?> object,Boolean ignoreSerialVersionUID) {
//设置忽略序列化Id默认值
if(null==ignoreSerialVersionUID){
ignoreSerialVersionUID=true;
}
//推断类型
List<String> objectFiledList = new ArrayList<>();
//获取类信息
Class<?> classInfo;
try {
//加载类信息
classInfo = Class.forName(object.getName());
//使用反射获取该类的成员属性
Field[] fieldList = classInfo.getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
//忽略获取序列化ID
if(ignoreSerialVersionUID){
//如果字段是序列化字段,则忽略
if (!fieldList[i].getName().equals("serialVersionUID")) {
objectFiledList.add(fieldList[i].getType().getSimpleName());
}
}else{
//序列化ID不忽略作为类的属性返回到结果中
objectFiledList.add(fieldList[i].getType().getSimpleName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return objectFiledList;
}
/**
* 获取一个类的成员属性的名称和类型Map集合(包括包名)
* @return Map<String,String>
* **/
public static Map<String,String> getClassFieldMap(Class<?> object,Boolean ignoreSerialVersionUID) {
//设置忽略序列化Id默认值
if(null==ignoreSerialVersionUID){
ignoreSerialVersionUID=true;
}
//推断类型
Map<String,String> classFiledMap = new HashMap<>();
//获取类信息
Class<?> classInfo;
try {
//加载类信息
classInfo = Class.forName(object.getName());
//使用反射获取该类的成员属性
Field[] fieldList = classInfo.getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
//忽略获取序列化ID
if(ignoreSerialVersionUID){
//如果字段是序列化字段,则忽略
if (!fieldList[i].getName().equals("serialVersionUID")) {
classFiledMap.put(fieldList[i].getName(),fieldList[i].getType().getName());
}
}else{
//序列化ID不忽略作为类的属性返回到结果中
classFiledMap.put(fieldList[i].getName(),fieldList[i].getType().getName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classFiledMap;
}
/**
* 获取类中所有成员属性的名称和类型Map集合(不包括包名)
* @return Map<String,String>
* **/
public static Map<String,String> getClassSimpleFieldMap(Class<?> object,Boolean ignoreSerialVersionUID) {
//设置忽略序列化Id默认值
if(null==ignoreSerialVersionUID){
ignoreSerialVersionUID=true;
}
//推断类型
Map<String,String> classFiledMap = new HashMap<>();
//获取类信息
Class<?> classInfo;
try {
//加载类信息
classInfo = Class.forName(object.getName());
//使用反射获取该类的成员属性
Field[] fieldList = classInfo.getDeclaredFields();
for (int i = 0; i < fieldList.length; i++) {
//忽略获取序列化ID
if(ignoreSerialVersionUID){
//如果字段是序列化字段,则忽略
if (!fieldList[i].getName().equals("serialVersionUID")) {
classFiledMap.put(fieldList[i].getName(),fieldList[i].getType().getSimpleName());
}
}else{
//序列化ID不忽略作为类的属性返回到结果中
classFiledMap.put(fieldList[i].getName(),fieldList[i].getType().getSimpleName());
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classFiledMap;
}
/************************方法类信息***********************************************/
/**
* 获取类中所有方法的名称列表
* @return List<String>
* **/
public static List<String> getClassMethodNameList(Class<?> object) {
List<String> classMethodNameList = new ArrayList<String>();
Class<?> classInfo;
try {
//获取类信息
classInfo = Class.forName(object.getName());
//根据反射获取类的方法
Method[] methodList = classInfo.getDeclaredMethods();
for (int i = 0; i < methodList.length; i++) {
classMethodNameList.add(methodList[i].getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classMethodNameList;
}
/**
* @description 获取类中所有方法返回类型列表(包括包名)
* @return List<String>
* **/
public static List<String> getClassMethodReturnTypeList(Class<?> object) {
List<String> classMethodReturnTypeList = new ArrayList<String>();
Class<?> classInfo;
try {
classInfo = Class.forName(object.getName());
Method[] methodList = classInfo.getDeclaredMethods();
for (int i = 0; i < methodList.length; i++) {
classMethodReturnTypeList.add(methodList[i].getReturnType().getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classMethodReturnTypeList;
}
/**
* @description 获取类中所有方法返回类型列表(不包括包名)
* @return List<String>
* **/
public static List<String> getClassMethodSimpleReturnTypeList(Class<?> object) {
List<String> classMethodReturnTypeList = new ArrayList<String>();
Class<?> classInfo;
try {
classInfo = Class.forName(object.getName());
Method[] methodList = classInfo.getDeclaredMethods();
for (int i = 0; i < methodList.length; i++) {
classMethodReturnTypeList.add(methodList[i].getReturnType().getSimpleName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classMethodReturnTypeList;
}
/**
* @description 获取类中所有方法名称和方法返回类型(包括包名)
* @return Map<String,String>
* **/
public static Map<String,String> getClassMethodInfoMap(Class<?> object) {
Map<String,String> classMethodInfoMap = new HashMap<>();
Class<?> classInfo;
try {
classInfo = Class.forName(object.getName());
Method[] methodList = classInfo.getDeclaredMethods();
for (int i = 0; i < methodList.length; i++) {
classMethodInfoMap.put(methodList[i].getName(),methodList[i].getReturnType().getName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classMethodInfoMap;
}
/**
* @description 获取类中所有方法名称和方法返回类型(不包括包名)
* @return Map<String,String>
* **/
public static Map<String,String> getClassSimpleMethodInfoMap(Class<?> object) {
Map<String,String> classMethodInfoMap = new HashMap<>();
Class<?> classInfo;
try {
classInfo = Class.forName(object.getName());
Method[] methodList = classInfo.getDeclaredMethods();
for (int i = 0; i < methodList.length; i++) {
classMethodInfoMap.put(methodList[i].getName(),methodList[i].getReturnType().getSimpleName());
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return classMethodInfoMap;
}
}