Java基础之反射技术相关知识总结

网友投稿 215 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 clazzB = Hero.class;

// 通过实例化对象获取

Class extends Hero> clazzC = (new Hero()).getClass();

// 基本类型的包装类的type获取

Class byteClazz = Byte.TYPE;

Class typeClazz = Short.TYPE;

Class integerClazz = Integer.TYPE;

Class longClazz = Long.TYPE;

Class floatClazz = Float.TYPE;

Class doubleClazz = Double.TYPE;

Class characterClazz = Character.TYPE;

Class booleanClazz = Boolean.TYPE;

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 listFields(Class> cls){

Field[] fs = cls.getDeclaredFields();

List fields = new ArrayList<>(Arrays.asList(fs));

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小时内删除侵权内容。

上一篇:多益网络策划分析师知识点
下一篇:无线网络技术——starlink(星链)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~