反射setaccessible_反射技术

cfd33138bbf8a023a71915f82b23da96.png

反射机制作用

  • 动态的加载类、动态的获取类的信息(属性,方法,构造器)
  • 动态构造对象
  • 动态调用类和对象的任意方法、构造器
  • 动态调用和处理属性
  • 获取泛型信息
  • 处理注解

获取Class对象的方式有哪些?

1. Class clazz = Class.forName(全限定类名);

2. 类名.class

3. 对象名.getClass();

反射机制动态操作方法_属性_构造器

使用反射机制获取类的名称和属性的方法有哪些?

String getName();获取包名+类名

String getSimpleName();获取类名

Field getField(String fieldName) 得到公共的属性对象

Field getDeclareField(String fieldName) 得到指定名称的属性对象

Field []c.getDeclaredFields() 得到所有的属性对象

使用反射机制获取方法及构造方法的方法有哪些?

Method[] getDeclaredMethods() 得到公共的方法对象

Method[] c.getMethods() 得到父类及本类中的公共的方法对象

Method getDeclaredMethod(String methodName, Class …type)得到指定名称的

本类中公共的方法

Method getMethod(String methodName,Class type)得到本类或父类中的公共的方法

对象

Constructor[] getDeclaredConstructors() 得到公共的构造方法的对象

Constructor [] getConstructors() 得到公共的构造方法对象

Constructor getDeclaredConstructor(Class...type)得到指定参数的公共的构造方法对象

package com.sxt.fanshe;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class TestClass {
	public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException {
		//(1)获取类的名称
		Class forName = Class.forName("com.sxt.entity.User");
		//2.类名.class
		//Class calzz = User.class;
		//3.对象名.getClass()
		//User user = new User();
		//Class clazz = user.getClass();
		System.out.println("类的全名称:"+forName.getName());//获取包名+类名
		System.out.println("类的名称:"+forName.getSimpleName());//获取类名
		//获取父类的
		System.out.println("父类的全名称:"+forName.getSuperclass().getName());
		System.out.println("父类的名称:"+forName.getSuperclass().getSimpleName());

		System.out.println("-------------------------------------");
		//(2)获取类的属性
		System.out.println("获取类的属性:");
		Field field = forName.getField("username");
		System.out.println(field);//只能获取公共的属性
		Field[] fields = forName.getFields();//只能获取所有公共属性
		System.out.println("公共属性值共有:"+fields.length);
		for (Field field2 : fields) {
			System.out.println(field2);
		}
		//获取所有属性值
		System.out.println("获取所有属性值:");
		Field[] field3 = forName.getDeclaredFields();
		System.out.println("属性值共有:"+field3.length);
		for (Field field4 : field3) {
			System.out.println(field4);
		}
		System.out.println("-------------------------------------");
		//获取方法值Method[] getDeclaredMethods() 得到公共的方法对象
		System.out.println("得到公共的方法对象:");
		Method[] methods = forName.getDeclaredMethods();
		for (Method method : methods) {
			System.out.println(method);
		}
		System.out.println("-------------------------------------");
		System.out.println("得到父类的方法对象:");
		Method[] methods2 = forName.getMethods();
		for (Method method : methods2) {
			System.out.println(method);
		}
		System.out.println("-------------------------------------");
		//获取构造器
		System.out.println("获取构造器");
		Constructor[] constructors = forName.getConstructors();
		for (Constructor constructor : constructors) {
			Class[] parameterTypes = constructor.getParameterTypes();//获取参数类型
			int cMod = constructor.getModifiers();//获取构造器修饰符
			String name = forName.getName();//获取名字
			System.out.println(cMod+"---"+name+"---"+Arrays.toString(parameterTypes));
			System.out.println(constructor);
		}
	}
}

b3612761b75e0355c9f79a1353d9f26a.png

提高反射效率

通过设置setAccessible(true);方法取消安全检查。禁止安全检查,可以提高反射的运行速度

package com.sxt.fanshe;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;


/**
 * 	提高效率setAccessible(true);禁用安全检查,可以提高运行速度
 * @date 2019年8月8日
 */
public class Test3 {
	public static void test01(){
		Object obj = new Object();
		long startTime = System.currentTimeMillis();//设置开始时间
		for (int i = 0; i < 1000000000; i++) {
			obj.hashCode();
		}
		long endTime = System.currentTimeMillis();//设置结束时间
		System.out.println("调用普通方法执行10亿次时间:"+(endTime-startTime)+"ms");
	}
	public static void test02() throws Exception{
		Object obj = new Object();
		Class clazz = obj.getClass();
		//获取hashcode方法
		Method method = clazz.getDeclaredMethod("hashCode", null);
		long startTime = System.currentTimeMillis();//设置开始时间
		for (int i = 0; i < 1000000000; i++) {
//			obj.hashCode();
			method.invoke(obj);
		}
		long endTime = System.currentTimeMillis();//设置结束时间
		System.out.println("调用反射回调方法执行10亿次时间:"+(endTime-startTime)+"ms");
	}
	public static void test03() throws Exception{
		Object obj = new Object();
		Class clazz = obj.getClass();
		//获取hashcode方法
		Method method = clazz.getDeclaredMethod("hashCode", null);
		method.setAccessible(true);//设置是否取消安全检查
		long startTime = System.currentTimeMillis();//设置开始时间
		for (int i = 0; i < 1000000000; i++) {
//			obj.hashCode();
			method.invoke(obj);
		}
		long endTime = System.currentTimeMillis();//设置结束时间
		System.out.println("调用优化后反射回调方法执行10亿次时间:"+(endTime-startTime)+"ms");
	}
	public static void main(String[] args) throws Exception {
		test01();
		test02();
		test03();
	}
}

66ece2d24f8e01806e21dc62b6f6f9d1.png

反射操作泛型

Java 中的泛型仅仅是给编译器 javac 使用的,确保数据的安全性和免去强制类型转换的麻烦,但是一旦编译完成,所有与泛型有关的类型全部擦除。

使用泛型直接读取泛型,是读取不到的,因为反射是操作加载以后的类的。

package com.sxt.fanshe;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

import com.sxt.entity.User;

public class TestGeneric {
	
	public void test01(Map<String,User> map,List<User> list,String s){
		System.out.println("TestGeneric.test01()");
	}
	public Map<Integer,User> test02(){
		System.out.println("TestGeneric.test02()");
		return null;
	}
	public String test03(){
		System.out.println("TestGeneric.test03()");
		return null;
	}
	public static void main(String[] args) throws NoSuchMethodException, SecurityException {
		//获取test01方法的泛型参数信息
		Class c=TestGeneric.class;
		Method test01=c.getMethod("test01", Map.class,List.class,String.class);
		
		//获取带泛型参数的类型
		Type [] tytes=test01.getGenericParameterTypes();
		System.out.println(tytes.length);
		for (Type type : tytes) {
			//System.out.println("#"+type);
			if (type instanceof ParameterizedType) {
				Type[] genericType= ((ParameterizedType) type).getActualTypeArguments();
				//遍历每一个泛型参数中泛型的类型  
				for (Type genType : genericType) {
					System.out.println("泛型类型:"+genType);
				}
				System.out.println("n--------------------------");
			}
		}
		
		System.out.println("n----------------------------n");
		//获取test02方法返回值的泛型信息
		Method m2=c.getMethod("test02", null);
		Type returnType=m2.getGenericReturnType();
		//判断是否带有泛型
		if(returnType instanceof ParameterizedType){
			Type [] types=((ParameterizedType) returnType).getActualTypeArguments();
			for (Type type : types) {
				System.out.println("返回值的泛型类型:"+type);
			}
		}
		
		System.out.println("n------------------------------n");
		Method m3=c.getMethod("test03", null);
		Type returnType3=m3.getGenericReturnType();
		//System.out.println(returnType3);
		System.out.println(returnType3 instanceof ParameterizedType);
	}
	
}

9b2aaa63550cc5eb675648ec0652d778.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用反射技术在Java中动态创建和操作类。以下是一个示例: ``` import java.lang.reflect.*; public class ReflectionExample { public static void main(String[] args) throws Exception { // 创建一个类名为Person的新类 Class<?> personClass = Class.forName("Person"); // 获取Person类的构造函数 Constructor<?> constructor = personClass.getConstructor(String.class, int.class); // 使用构造函数实例化一个Person对象 Object personObject = constructor.newInstance("Tom", 25); // 获取Person对象的名称和年龄属性 Field nameField = personClass.getDeclaredField("name"); Field ageField = personClass.getDeclaredField("age"); // 设置Person对象的名称和年龄属性值 nameField.setAccessible(true); ageField.setAccessible(true); nameField.set(personObject, "Jerry"); ageField.set(personObject, 30); // 获取Person对象的toString()方法 Method toStringMethod = personClass.getMethod("toString"); // 调用Person对象的toString()方法并输出结果 String result = (String) toStringMethod.invoke(personObject); System.out.println(result); } } class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } ``` 运行以上代码,将会输出以下结果: ``` Person{name='Jerry', age=30} ``` 通过反射技术,我们动态创建了一个名为Person的类,并实例化了一个Person对象。然后,我们使用反射技术访问并修改了Person对象的属性,最后调用了Person对象的toString()方法并输出了结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值