java获取对象属性类型、属性名称、属性值:https://www.cnblogs.com/gmq-sh/p/5942065.html
利用java的反射
Class类有什么作用?
(1) Class 类的实例表示正在运行的 Java 应用程序中的类和接口,反射的一大好处就是可以允许我们在运行期间获取对象的类型信息。
(2) Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。
(3) 在Java中,每一个Object都有一个getClass()方法,通过getClass方法我们可以获取到这个对象对应的反射类:obj.getClass()。
(4) 装载类的过程非常简单:查找类所在位置,并将找到的Java类的字节码装入内存,生成对应的Class对象,Java的类装载器专门用来实现这样的过程。
(5) 虚拟机JVM并不止有一个类装载器,类装载器自身也是一个类,它也需要被装载到内存中来,那么这些类装载器由谁来装载呢,总得有个根吧?没错,确实存在这样的根,它就是神龙见首不见尾的Bootstrap ClassLoader。
(6) 这java的运行环境所需要的所有类库,都由Bootstrap ClassLoader来装载,而它本身是C++写的程序,可以独立运行,可以说是JVM的运行起点。
(7) 在Bootstrap完成它的任务后,会生成一个AppClassLoader(实际上之前系统还会使用扩展类装载器ExtClassLoader,它用于装载Java运行环境扩展包中的类),这个类装载器才是我们经常使用的,可以调用ClassLoader.getSystemClassLoader() 来获得。
(8) 这AppClassLoader查找类的区域就是耳熟能详的Classpath,我们按照它的类查找范围给它取名为类路径类装载器。
(9) 当Java中出现新的类,AppClassLoader首先将该类传递给它的父类类装载器,也就是Extion ClassLoader,询问它是否能够装载该类,如果能,那AppClassLoader就不干这活了,同样Extion ClassLoader在装载时,也会先问问它的父类装载器。我们可以看出类装载器实际上是一个树状的结构图,每个类装载器有自己的父亲,类装载器在装载类时,总是先让自己的父类装载器装载(多么尊敬长辈),如果父类装载器无法装载该类时,自己就会动手装载,如果它也装载不了,那么对不起,它会大喊一声:Exception,class not found。有必要提一句,当由直接使用类路径装载器装载类失败抛出的是NoClassDefFoundException异常。如果使用自定义的类装载器loadClass方法或者ClassLoader的findSystemClass方法装载类,如果你不去刻意改变,那么抛出的是ClassNotFoundException。
(10) obj.getClass().getClassLoader():取得该Class对象的类装载器。
(11) 我们也可以调用Class类的静态方法forName():Class<?> c = Class.forName("java.lang.String");
(12) 我们也可以直接使用.class:Class<?> c = String.class;
(13) Method Class.getMethod(String name, Class<?>... parameterTypes)的作用是获得对象所声明的公开方法 该方法的第一个参数name是要获得方法的名字,第二个参数parameterTypes是按声明顺序标识该方法形参类型。
(14) 利用反射我们可以写出更加清晰的测试代码,其中getDeclaredMethods()方法可以获取相关对象自己声明的相关方法,而getAnnotation()则可以获取Method对象的指定注解: http://www.importnew.com/24042.html
package com.Util;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserCase {
public int id();
public String description() default "no description";
}
package com.Util;
import java.util.List;
public class PasswordUtils {
@UserCase(id=47, description="----验证密码格式------")
public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UserCase(id=48,description="----加密------")
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
}
@UserCase(id=49, description="------新旧密码验证------")
public boolean checkForNewPassword(List<String> prevPasswords, String password) {
return !prevPasswords.contains(password);
}
}
package com.Util;
import com.Util.UserCase;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class UseCaseTracker {
public static void trackUseCases(List<Integer> intList, Class<?> c) {
//遍历——java类的反射类的反射方法
for(Method m : c.getDeclaredMethods()) {
//通过java类的反射类获取注解对象
UserCase uc = m.getAnnotation(UserCase.class);
//如果注解对象不为空,则打印其id
if(uc != null) {
System.out.println("Found UserCase: " + uc.id() + " " + uc.description());
//在容器中移除注解对象的id
intList.remove(new Integer(uc.id()));
}
}
for(int i : intList) {
System.out.println("警告: 缺失 userCase-" + i);
}
}
public static void main(String[] args) {
List<Integer> userCases = new ArrayList<Integer>();
Collections.addAll(userCases, 47, 48, 49, 50);
trackUseCases(userCases, PasswordUtils.class);
}
}
自定义(对象转化为集合Map的)工具类:
package com.Util;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
public class ObjectToMapUtil {
/**
* getFields():获得某个类的所有的公共(public)的字段,包括父类中的字段。
* getField(String fieldName)
* getDeclaredFields():获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。
* getDeclaredField(String fieldName)
*/
public static Map<String,Object> toMap(Object obj){
//新建-Map
Map<String,Object> m = new HashMap<String,Object>();
//获取-对象的属性定义
Field[] fields=obj.getClass().getDeclaredFields();
//循环-对象的属性定义
for(Field f:fields){
m.put(f.getName(), getFieldValueByName(f.getName(),obj));
}
return m;
}
/**根据属性名获取属性值:
(1)获取对象所对应的类的方法:
Method method = XXX.getClass().getMethod(方法名methodName,形参类型Class<?>... parameterTypes);
(2)java反射中method类中的invoke方法——其作用就是调用XXX对象中的方法:
method.invoke(该方法的拥有者对象XXX, 形参对象Object<?>... parameterObject)
(3)如何获取属性值**/
public static Object getFieldValueByName(String fieldName, Object obj) {
try {
String firstLetter = fieldName.substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldName.substring(1);
Method method = obj.getClass().getMethod(getter, new Class[] {});
Object value = method.invoke(obj, new Object[] {});
return value;
} catch (Exception e) {
System.out.println("----------根据属性名获取属性值-失败!-----------");
return null;
}
}
/*测试*/
/* String[] arg为主线程运行时的初始参数 */
public static void main(String[] arg) {
ObjectToMapUtil.User u = new ObjectToMapUtil.User("嫦娥", "1314520");
System.out.println("对象转化为map的结果:" + ObjectToMapUtil.toMap(u).toString());
}
/* 静态内部类 */
static class User {
private static final long serialVersionUID = 4851912670935014257L;
private String name;
private String pwd;
public User(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public String getName() {
return this.name;
}
public String getPwd() {
return this.pwd;
}
public void setName(String name) {
this.name = name;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
}
自定义多级菜单(递归(父子关系))
package com.Util;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.Entity.Permission;
import com.alibaba.fastjson.JSON;
public class RecursiveUtil {
private List<Object> list;
private String fieldName_For_Id_Of_Parent;//父节点的主键的字段名
private String fieldName_For_ParentId_Of_Childs;//孩子节点的ParentId的字段名
private String fieldName_For_Url_Of_Parent;//父节点的(用于存储链接地址)的字段的名称,也可以说是(标记叶子节点)的字段的名称
//构造函数
public RecursiveUtil(List<Object> list,
String fieldName_For_Id_Of_Parent,
String fieldName_For_ParentId_Of_Childs,
String fieldName_For_Url_Of_Parent){
this.list = list;
this.fieldName_For_Id_Of_Parent = fieldName_For_Id_Of_Parent;
this.fieldName_For_ParentId_Of_Childs = fieldName_For_ParentId_Of_Childs;
this.fieldName_For_Url_Of_Parent = fieldName_For_Url_Of_Parent;
}
//过滤并转化为List<Map<String,Object>>,fieldValue_For_ParentId_Of_Childs代指孩子节点的父节点id的值
private List<Map<String,Object>> getChilds(String fieldValue_For_ParentId_Of_Childs){
List<Map<String, Object>> childs = new ArrayList<Map<String,Object>>();
//找出当前父节点的所有子节点,把它们放入新建的childs里面,返回childs
for(int i=0;i<list.size();i++){
if(ObjectToMapUtil.getFieldValueByName(fieldName_For_ParentId_Of_Childs, list.get(i))==fieldValue_For_ParentId_Of_Childs){
childs.add(ObjectToMapUtil.toMap(list.get(i)));//添加
}
}
return childs;
}
//递归——Map<String,Object>>——{child:[{},{}]}——回调函数
public void parentAndChildren(Map<String,Object> parent){
//结束条件,如果fieldName_For_Url_Of_Parent对应的值不为空,说明为叶子节点
if(null!=parent.get(fieldName_For_Url_Of_Parent))
return;
//获取父节点的id
String id;
//如果参数parent内容为空,代表其孩子节点的父节点为空,故我们需要将其主键字段值设为null
if(parent.isEmpty()){
id = null;
}else{
id = (String)parent.get(fieldName_For_Id_Of_Parent);//否则获取parent的主键值
}
//遍历list,找出父节点为id的子节点,并放入父节点的属性"childs"中
List<Map<String,Object>> childsMap =getChilds(id);
parent.put("childs", childsMap);
for(Map<String,Object> m:childsMap){
//自己调用自己
parentAndChildren(m);
}
}
public static void main(String[] args){
/**起始时间**/
Date initDate = new Date();
List<Object> list =new ArrayList<Object>();
Permission per1=new Permission();
per1.setId("1");
per1.setName("系统管理");
Permission per11=new Permission();
per11.setId("11");
per11.setName("用户管理");
per11.setParentid("1");
Permission per111=new Permission();
per111.setId("111");
per111.setName("客户管理");
per111.setUrl("userManager");
per111.setParentid("11");
Permission per112=new Permission();
per112.setId("112");
per112.setName("管理员管理");
per112.setUrl("sysUserManager");
per112.setParentid("11");
list.add(per1);
list.add(per11);
list.add(per111);
list.add(per112);
//创建一个RecursiveUtil对象
RecursiveUtil rec = new RecursiveUtil(list,"id","parentid","url");
//新建一个结果对象result
Map<String,Object> result=new HashMap<String,Object>();
//通过回调函数parentAndChildren(result),对result进行处理
rec.parentAndChildren(result);
//调用fastJson包的JSON.toJSONString(Object obj)转化为json格式
System.out.println(JSON.toJSONString(result));
/**结束时间**/
Date endDate = new Date();
//时间间隔(单位:微秒)
long microSecondInterval = (endDate.getTime() - initDate.getTime());
//时间间隔(单位:秒)
double SecondInterval =((double)microSecondInterval)/1000;
System.out.println("运行时间间隔:"+SecondInterval+"秒");
}
}