Flask接口签名sign原理与实例代码浅析
235
2022-10-23
Java基础之反射技术相关知识总结
一、反射概念
java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
二、反射应用场景
1.几乎所有的框架都会用到反射
2.程序解耦合使用
3.代码更加的优雅
三、反射更多细节
1.Jdk中的位置: java.lang.reflect包下
2.获取字节码方式
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 通过类直接获取
Class
// 通过实例化对象获取
Class extends Hero> clazzC = (new Hero()).getClass();
// 基本类型的包装类的type获取
Class
Class
Class
Class
Class
Class
Class
Class
3.测试类Hero省略Setter和Getter以及toString方法其中包含无参构造和满参构造
package com.open_source.demo.domain;
/**
* 英雄实体类
*
* @author: tyvek
*/
public class Hero {
/**
* 类型
*/
vxyPaNzKWprivate String type;
/**
* 姓名
*/
private String name;
/**
* 战力
*/
private Double CE;
/**
* 打印英雄属性
*
* @param hero 英雄对象
*/
public void attrbute(Hero hero) {
System.out.println(hero.getType() + ": " + hero.getName() + "输出伤害: " + hero.getCE());
}
/**
* 为队友加油
*/
public void fighting() {
System.out.println("稳住 我们能赢");
}
/**
* 向英雄发起进攻
*
* @param name 英雄名字
*/
public void attack(String name) {
System.out.println("准备向" + name + "发起进攻");
}
public Hero(String type, String name, Double CE) {
this.type = type;
this.name = name;
this.CE = CE;
}
public Hero() {
}
}
4.获取类的成员
获取类的构造函数
import java.util.StringJoiner;
/**
* 反射测试类
* @author: tyvek
*/
public class ReflectClient {
public static void main(String[] args) throws ClassNotFoundException {
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 获取所有构造函数字节码
Constructor>[] declaredConstructors = clazzA.getDeclaredConstructors();
// 打印构造函数修饰符以及参数类型
for (int i = 0; i < declaredConstructors.length; i++) {
// 美化输出
StringJoiner sj = new StringJoiner(", ","[","]");
System.out.print("构造函数修饰符:" + Modifier.toString(declaredConstructors[i].getModifiers()) + " 参数类型:");
Class>[] parameterTypes = declaredConstructors[i].getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
sj.add(parameterTypes[j].getName());
}
System.out.println(sj.toString());
}
}
}
// 打印内容
构造函数修饰符:public 参数类型:[java.lang.String, java.lang.String, java.lang.Double]
构造函数修饰符:public 参数类型:[]
获取指定构造函数
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 获取满参构造
Constructor> allArgsConstrucvxyPaNzKWtor = clazzA.getDeclaredConstructor(String.class, String.class, Double.class);
// 获取无参构造
Constructor> nonehttp://ArgConstructor = clazzA.getDeclaredConstructor();
调用构造函数
public class ReflectClient {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 获取满参构造
Constructor> allArgsConstructor = clazzA.getDeclaredConstructor(String.class, String.class, Double.class);
// 获取无参构造
Constructor> noneArgConstructor = clazzA.getDeclaredConstructor();
// 如果修饰符为private需要使用暴力反射
// noneArgConstructor.setAccessible(true);
Hero hero = (Hero) noneArgConstructor.newInstance();
hero.setType("射手");
hero.setName("后裔");
hero.setCE(1000.0);
System.out.println(hero);
Hero heroAll = (Hero) allArgsConstructor.newInstance("法师", "诸葛亮", 1000.1);
heroAll.attrbute(heroAll);
}
}
// 控制台输出
Hero{type='射手', name='后裔', CE=1000.0}
法师: 诸葛亮 输出伤害: 1000.1
获取成员方法
public class ReflectClient {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 获取无参构造
Constructor> noneArgConstructor = clazzA.getDeclaredConstructor();
Hero hero = (Hero) noneArgConstructor.newInstance();
// 获取所有成员方法
Method[] declaredMethods = clazzA.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++) {
StringJoiner sj = new StringJoiner(",", "[", "]");
System.out.print("方法名称:" + declaredMethods[i].getName() + " 方法参数: ");
Class>[] parameterTypes = declaredMethods[i].getParameterTypes();
for (int j = 0; j < parameterTypes.length; j++) {
sj.add(parameterTypes[j].getName());
}
System.out.println(sj.toString());
}
}
}
// 控制台输出
方法名称:attrbute 方法参数: [com.open_source.demo.domain.Hero]
方法名称:attack 方法参数: [java.lang.String]
set和get省略
方法调用
// 获取attack字节码对象
Method attackMethod = clazzA.getDeclaredMethod("attack", String.class);
// 如果修饰符为private同样需要使用暴力反射
attackMethod.invoke(hero,"周瑜");
// 控制台输出
准备向周瑜发起进攻
获取所有的成员属性
public class ReflectClient {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero");
// 获取所有成员属性
Field[] declaredFields = clazzA.getDeclaredFields();
Stream.of(declaredFields).forEach(System.out::println);
}
}
// 控制台输出
private java.lang.String com.open_source.demo.domain.Hero.type
private java.lang.String com.open_source.demo.domain.Hero.name
private java.lang.Double com.open_source.demo.domain.Hero.CE
获取父类的字节码
// 通过类的全限定类名获取
Class> clazzA = Class.forName("com.open_source.demo.domain.Hero").getSuperclass();
反射工具类
package com.open_source.demo.support;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* @author: tyvek
* 反射工具类
*/
public class ReflectSupport {
private ReflectSupport(){};
/**
* 获取字段对应值,并转为String类型,空值返回空字符串
* @param fieldName
* @param obj
* @return
*/
public static synchronized String getStringValue(String fieldName,Object obj) throws ReflectiveOperationException{
Object objectValue = getValueByGetter(fieldName,obj);
if (objectValue == null){
return "";
}
String result = objectValue.toString();
//如果类型为BigDecimal,去掉末尾的0
if (objectValue instanceof BigDecimal){
BigDecimal value = (BigDecimal) objectValue;
value = value.stripTrailingZeros();
result = value.toPlainString();
}else if (objectValue instanceof Date){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
result = sdf.format((Date)objectValue).replace(" 00:00:00", "");
}
return result.trim();
}
public static Object getValueByGetter (String fieldName,Object obj) throws ReflectiveOperationException {
Method getter = getGetter(fieldName, obj.getClass());
if (getter != null){
return getter.invoke(obj);
}
return null;
}
public static Object setValueBySetter (String fieldName,Object obj) throws ReflectiveOperationException {
Method setter = getSetter(fieldName, obj.getClass());
if (setter == null){
throw new ReflectiveOperationException("没有set方法");
}
return setter.invoke(obj);
}
/**
* 获取get方法
* @param fieldName
* @param cls
* @return
*/
public static Method getGetter(String fieldName,Class> cls){
for (Method method : cls.getMethods()) {
if (method.getName().equalsIgnoreCase("get".concat(fieldName)) && method.getParameterTypes().length == 0){
return method;
}
}
return null;
}
/**
* 获取set方法
* @param fieldName
* @param cls
* @return
*/
public static Method getSetter(String fieldName,Class> cls){
for (Method method : cls.getMethods()) {
if (method.getName().equalsIgnoreCase("set".concat(fieldName)) && method.getParameterTypes().length == 0){
return method;
}
}
return null;
}
/**
* 通过属性名获取Field对象
* @param fieldName
* @param cls
* @return
*/
public static synchronized Field getFieldByName(String fieldName,Class> cls){
Field[] fields =cls.getDeclaredFields();
for (Field field : fields){
if (field.getName().equals(fieldName)){
return field;
}
}
if (cls.getSuperclass() != null){
return getFieldByName(fieldName,cls.getSuperclass());
}
return null;
}
/**
* 通过对象.class获取所有Fields,包括父类
* @param cls
* @return
*/
public static List
Field[] fs = cls.getDeclaredFields();
List
if (cls.getSuperclass() !=null){
fields.addAll(listFields(cls.getSuperclass()));
}
return fields;
}
public static boolean fieldExist(String fieldName,Class> cls){
return getFieldByName(fieldName, cls) !=null;
}
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~