博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java基础review(4)---java反射
阅读量:4075 次
发布时间:2019-05-25

本文共 5054 字,大约阅读时间需要 16 分钟。

java反射

一、理论

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

二、案例演示

/**	 * 演示类	 */	public static class Person {		static {			System.out.println("静态代码块执行");		}		private Integer id;		private String name;		public Person(Integer id, String name) {			super();			this.id = id;			this.name = name;		}		public Person() {			super();		}		public Integer getId() {			return id;		}		public void setId(Integer id) {			this.id = id;		}		public String getName() {			return name;		}		public void setName(String name) {			this.name = name;		}		@Override		public String toString() {			return "Person [id=" + id + ", name=" + name + "]";		}			}

1、获取class对象的三个方式

/**	 * 	类.class	 *  对象.getClass	 *  Class.forName	 */	@Test	public void test1() throws Exception {		String className = "d18_reflect.review.ReflectDemo.Person";		Class
clazz = Class.forName(className); // 方式1 clazz = Person.class; // 方式2 clazz = new Person().getClass(); // 方式3 }

2、class.forName() 三个参数以及自设类加载器候补顺序

* 自设定类加载器数组的顺序一般是:自设,Thread,本类,system。	 * forName第二个参数如果为false,那么静态代码块不执行。	 */	@Test	public void test2() throws Exception {		String className = "d18_reflect.review.ReflectDemo$Person";		ClassLoader cl = new ClassLoader[]{Thread.currentThread().getContextClassLoader(), getClass().getClassLoader(), 				 ClassLoader.getSystemClassLoader()}[1];		Class
clazz = Class.forName(className, true, cl); // 为false,静态代码块不执行 }

 3、Method的反射

* getDeclaredMethods : 本类的所有方法	 * getMethods:本类的公开方法含父类	 */	@Test	public void test3() throws Exception {		Class
clazz = Person.class; Person person = (Person)clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); // 所有本类声明的方法 for (Method method : methods) { System.out.println(method); } System.out.println("_______________"); Method[] methods2 = clazz.getMethods(); //本类所有公开的方法 for (Method method : methods2) { System.out.println(method); } Method method = clazz.getMethod("setName",new Class[]{String.class}); System.out.println(method); Object object = method.invoke(person, "哈哈"); //方法执行 }

 4、Field的反射

* getDeclaredFields : 本类的声明字段	 * getFields:全部公开字段	 * setAccessible(true) 可访问公开字段	 */	@Test	public void test4() throws Exception{		Person demo = new Person();		Class
clazz1 = Person.class; Field[] fields = clazz1.getFields(); for (Field field : fields) { System.out.println("全部公开字段"+field.getName()); } Field[] fields2 = clazz1.getDeclaredFields(); for (Field field : fields2) { System.out.println("本类声明字段:"+field.getName()); } //测试如何调用一个字段? Field declaredField = clazz1.getDeclaredField("name"); declaredField.setAccessible(true); //暴力反射,私有字段采用 declaredField.set(demo,"5"); Object object = declaredField.get(demo); System.out.println(object.toString()); }

5、数组的反射

/**	 * 5、数组的反射	 * clazz.isArray() : 判断是数组	 * Array.getLength : 数组长度	 * Array.get(arr, 3):数组角标3的元素	 */	@Test	public void test5() throws Exception{		Object[] arr = new String[5];		for (int i = 0; i < arr.length; i++) {			arr[i] = i +"";		}		Class
class2 = arr.getClass(); if(class2.isArray()){ System.out.println(Array.getLength(arr)); System.out.println(Array.get(arr, 3)); } }

6、泛型反射

class Parent
{} class Student extends Parent
{} class StudentExt extends Student{} /** * 6、泛型反射 * getGenericSuperclass : 带泛型参数的父类 * ParameterizedType : type的子接口 * ParameterizedType.getActualTypeArguments : 真实类型参数的数组 */ @Test public void test6() {// System.out.println(Object.class.getSuperclass()); //null// System.out.println(Student.class.getSuperclass());//class d18_reflect.review.ReflectDemo$Parent// System.out.println(Student.class.getGenericSuperclass());//d18_reflect.review.ReflectDemo$Parent
Class
clazz = findTtype(Person.class); System.out.println(clazz); } /** * 父级泛型参数的类型查询-只支持2级查询 */ public static Class
findTtype(Class
entity){ Type type = entity.getGenericSuperclass(); // 带泛型参数的类型,class父接口 if (!(type instanceof ParameterizedType)) { type = entity.getSuperclass().getGenericSuperclass(); } ParameterizedType parameterizedType = (ParameterizedType) type; Class entityClass = (Class) parameterizedType.getActualTypeArguments()[0]; return entityClass; } /** * 通过继承方式TypeReference类方式,获取子类传递的实际泛型参数 */ abstract class TypeReference
{ private final Type rawType; protected TypeReference() { rawType = getSuperclassTypeParameter(getClass()); } Type getSuperclassTypeParameter(Class
clazz) { Type genericSuperclass = clazz.getGenericSuperclass(); if (genericSuperclass instanceof Class) { if (TypeReference.class != genericSuperclass) { return getSuperclassTypeParameter(clazz.getSuperclass()); } } Type rawType = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[0]; if (rawType instanceof ParameterizedType) { rawType = ((ParameterizedType) rawType).getRawType(); } return rawType; } public final Type getRawType() { return rawType; } }

 

 

 

 

转载地址:http://seuni.baihongyu.com/

你可能感兴趣的文章
attenuation
查看>>
Unity2017五子棋大战_人机_双人_UNET联网
查看>>
英文谚语:Take that with a grain of salt
查看>>
Which is totally fine
查看>>
Individual
查看>>
Hands-On Unity 2018 x 移动游戏开发教程
查看>>
compatible
查看>>
左手坐标系
查看>>
大爆炸(Big Bang)
查看>>
weld
查看>>
现在的产品和策划都是蠢猪,居然还不开发区块链游戏
查看>>
effector - 必应词典
查看>>
KBEngine 编译出现 MSB802 无法找到v140的生成工具
查看>>
测不准原理主要指向微观
查看>>
C#之SByte
查看>>
C#使用 params object[] 将参数个数不一样的方法 集成一个
查看>>
Why is it called “armature” instead of “skeleton”? or perhaps “rig”?
查看>>
flock - 必应词典
查看>>
Beyond Compare 4 提示错误“这个授权密钥已被吊销”的解决办法
查看>>
微软必应Bing搜索引擎这几天无法访问!
查看>>