实现以上场景,在java中有多种方法,最直接方式的是通过反射获取,但是反射有较大的性能损耗,一般不建议用在运行阶段反射,大多开源框架是在初始化的时候通过反射来实例化。
1、通过反射获取
package test;import javalangreflectField;
public class Demo2 {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
String op = "strA";
Test t = new Test();
// /通过类的字节码得到该类中声明的所有属性,无论私有或公有
Field strs = TestclassgetDeclaredField(op);
// 设置访问权限(这点对于有过android开发经验的可以说很熟悉)
strssetAccessible(true);
// 得到私有的变量值
String[] as = (String[]) strsget(t);
Systemoutprintln(aslength);
}
}
class Test {
private String[] strA = new String[]{"a","b","c"};
private String[] strB = new String[]{"d","e","f"};
}
2、通过map设置获取
package test;
import javautilHashMap;
import javautilMap;
public class Demo2 {
public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
Map<String,String[]> map = new HashMap<String,String[]>();
mapput("strA", new String[]{"a","str","c"});
mapput("strB", new String[]{"d","e","f"});
String op = "strB";
String result = mapget(op)[0]; // "d"
}
}
以上两种方法虽然都能实现需求,但是在实际情况中还是得看具体的情况来界定选择。
反射type,直接拿呀
Type t = 你对象GetType();
PropertyInfo[] pis = tGetProperties(); //属性
var funs = tGetMethods();//拿方法
var mems = tGetMembers(); //拿所有成员
然后foreach了
java反射获取属性值是怎样的呢?一起来看下吧:
反射获取Java类的所有字段,包括所有父类中的字段。类自身的字段可直接通过方法getDeclaredFields()(获取所有修饰符字段)或者getFields()(获取public修饰的字段)获取,但父类中的字段暂时没有发现直接获取的方式。 需要递归获取所有的父类,然后获取他们的字段,最终获取到类的所有字段。
如果要获取字段值,则需要设置字段可访问:fieldsetAccessible(true); field为reflect包下的Field类
案例:
1、父类
package comcarlstudyspringbootbean; import lombokData; import lombokexperimentalAccessors; / @author changez @desc @date 2019/3/10 11:30 / @Data @Accessors(chain = true) public class BeanBasic { private Integer id; private Long createTime; private Long updateTime; }
2、子类
package comcarlstudyspringbootbean; import lombokData; import lombokEqualsAndHashCode; import lombokToString; import lombokexperimentalAccessors; / @author changez @desc @date 2019/3/10 11:17 / @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @Accessors(chain = true) public class Student extends BeanBasic{ private String name; private String address; }
3、测试类
package testlombok; import comcarlstudyspringbootbeanStudent; import orgjunitTest; import javalangreflectField; import javautilArrayList; import javautilArrays; import javautilList; / @author changez @desc Java反射获取类的所有属性 @date 2019/3/10 11:41 / public class LombokTest { @Test public void getParentField(){ Student stu1 = new Student(); stu1setName("student-name") setAddress("student1-address") setId(1) setCreateTime(20190310140423L) setUpdateTime(20190310140423L) ; Class clazz = Studentclass; List allFields = new ArrayList(100); // 获取当前对象的所有属性字段 // clazzgetFields():获取public修饰的字段 // clazzgetDeclaredFields(): 获取所有的字段包括private修饰的字段 allFieldsaddAll(ArraysasList(clazzgetDeclaredFields())); // 获取所有父类的字段, 父类中的字段需要逐级获取 Class clazzSuper = clazzgetSuperclass(); // 如果父类不是object,表明其继承的有其他类。 逐级获取所有父类的字段 while (clazzSuper != Objectclass) { allFieldsaddAll(ArraysasList(clazzSupergetDeclaredFields())); clazzSuper = clazzSupergetSuperclass(); } allFieldsstream()forEach(field -> { // 设置字段可访问, 否则无法访问private修饰的变量值 fieldsetAccessible(true); try { // 获取字段名称 String fieldName = fieldgetName(); // 获取指定对象的当前字段的值 Object fieldVal = fieldget(stu1); Systemoutprintln(fieldName+"="+fieldVal); } catch (IllegalAccessException e) { eprintStackTrace(); } }); } }
TgetClass()或者Tclass都是非法的,因为T是泛型变量。
由于一个类的类型是什么是在编译期处理的,故不能在运行时直接在Base里得到T的实际类型。
有一种变通的实现方式:
import javalangreflectArray;
import javalangreflectParameterizedType;
import javalangreflectType;
public class Generic extends Base<String> {
public static void main(String[] args) {
Generic c = new Generic();
Systemoutprintln(carray);
}
Object array ;
public Generic() {
array = ArraynewInstance(getGenericType(0), 100);
}
}
class Base<T> {
public Class getGenericType(int index) {
Type genType = getClass()getGenericSuperclass();
if (!(genType instanceof ParameterizedType)) {
return Objectclass;
}
Type[] params = ((ParameterizedType) genType)getActualTypeArguments();
if (index >= paramslength || index < 0) {
throw new RuntimeException("Index outof bounds");
}
if (!(params[index] instanceof Class)) {
return Objectclass;
}
return (Class) params[index];
}
}
其中Base<T>是泛型类,在父类中声明getGenericType,子类继承具体的Base<String>,那么在子类中就可以通过getGenericType(0)获取到String的class
以上就是关于java 中怎么获得以该字符串命名的变量全部的内容,包括:java 中怎么获得以该字符串命名的变量、怎么使用c#反射只拿到成员变量、java反射获取属性值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)