黑马程序员-Class类, Constructor类,Field类, Method类的小总结

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


Class类
用于描述的事物就是java中的各种类。
Class类的对象:是内存中的一段字节码。
java程序运行时,会从硬盘中读取类的.class文件,然后把这个文件中的二进制代码段加载入内存,才能运行。而Class类的对象就是内存中这些类的二进制字节码。
可以从一个已知类得到这个类的Class对象:
Class cls=Person.class; 
也可以 Class cls=System.Person;
也可以  Clsaa cls=Class.forName("...Person");//参数为一个类名包含包名的全称
同样可以从Person类的对象那里得到Person类的字节码。
如 Person p=new Person();
   Class cls=p.getClass();
java中有9个预定义的Class对象,是8个基本类型的Class对象和void的Class对象。
Class的常用方法:
isPrimitive();//判断这个类是否基本类型
isArray();//判断是不是数组类型

包装类.TYPE 返回的是此包装类所包装的基本类型的Class对象。如Integer.TYPE就是int.class

		String str1="abc";
		Class cls1=str1.getClass();
		Class cls2=String.class;
		Class cls3=Class.forName("java.lang.String");
		System.out.println(cls1==cls2);//true
		System.out.println(cls2==cls3);//true
		System.out.println(cls1.isPrimitive());//判断这个类是否基本类型 false
		System.out.println(int.class.isPrimitive());// true
		System.out.println(int.class==Integer.class);//false
		System.out.println(int.class==Integer.TYPE);//TYPE代表的是Integer所包装的基本类型的字节码 true
		System.out.println(int[].class.isPrimitive());//数组类型不是基本类型(废话) false
		System.out.println(int[].class.isArray());//判断是不是数组类型 true


Constructor类:构造方法的反射。
Constructor[] constructors=Class.forName("java.lang.String").getConstructors();//得到String类的所有构造方法对象并存放于一个Constructor数组中。
Class的getConstructor(参数类的Class对象)方法,得到一个类的构造方法,具体哪个构造方法需要靠参数决定。如
Constructor cons=String.class.getConstructor(StringBuffer.class);//得到String类的构造方法,此构造方法是传一个StringBuffer参数的那个构造方法。
String str2=(String)cons.newInstance(new StringBuffer("abcdefg"));//用已得到的构造方法,传入相应的参数,得到一个对象。编译阶段jvm不知道cons是哪个类的构造方法,编译时期只定义不赋值,只有到了运行阶段才执行第一行的赋值运算,也就是运行阶段才能知道cons是哪个类的构造方法。所以编译之前要做一个强制类型转换,指定得到的对象的类型。

上面的思想是Class->Constructor->类对象。如果调用的是默认的不带参数的构造方法,那么可以通过Class.newInstance()方法来直接获取类对象,跳过中间Constructor那一步。如
String obj=(String)Class.forName("java.lang.String").newInstance();
运用反射会是计算机性能下降,所以在java源代码中Class的constructor方法中会运用缓存来处理constructor对象。

Field类:成员变量的反射
Class对象的getField("变量名")方法。得到一个类中的某个公有变量对象,返回类型为Field。
Fild对象的get(Object obj)方法。得到此变量在obj对象中的值。
Field fieldY=pt1.getClass().getField("y");//getField("y")得到类里面y变量的对象

System.out.println(fieldY.get(pt1));//得到y变量对象在pt1对象中的值,即pt1身上的y对象的值

Class对象的getDeclaredField("变量名")方法,看到一个类中某变量对象,无论此变量是否私有,返回类型为Field
Field对象的setAccessible(true)方法,将此对象强行设为可以访问。(暴力反射)
Field对象的get(Object obj)方法。得到此变量在obj对象中的值。
Field fieldX=pt1.getClass().getDeclaredField("x");//x是私有的,不可见。getDeclaredField("x")得到的变量忽视可见或不可见,统统可以看到,但是不可访问
fieldX.setAccessible(true);//将x对象设为可访问的(暴力反射)
System.out.println(fieldX.get(pt1));
Field对象的getType()方法,返回这个变量的类型的Class对象。

Field对象的set(obj,newvalue)方法,设置对象obj中此变量的值为newvalue。

//这里用== 而不是equals,因为Class对象是字节码,每一个类的字节码在内存中都是唯一的一份,就直接用==比较地址
			 if(field.getType()==(Class.forName("java.lang.String"))){//判断变量对象的类是否是String
				 String oldvalue =(String)field.get(obj);//得到String变量的值
				 String newvalue =oldvalue.replace('b', 'a');//替换得新值
				 field.set(obj, newvalue);//把新值导入
}


Method类,成员方法的反射。
Class对象的getMethod("方法名",参数类型的Class对象)方法。得到的是某个类的指定方法对象,类型是Method。

Method对象的invoke(对象,参数)方法。一个对象执行这个Method对象所代表的方法,参数即Method对象所代表的方法所带的参数。如果这个Method对象所代表的的方法是静态的,那么invoke参数中的类对象就是null。

//main()方法中传递参数是一个String数组,但是如果手动向里面传递一个String数组的话,java会默认把数组拆开一层,认为传来的
//是多个字符串。这时,就要把这个String数组再打包到一个Object数组对象里面,它被拆了就得到一个String数组对象了
mainMethod.invoke(null,new Object[]{new String[]{"ss","aa","bb"}});//执行main方法


---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
反射是 Java 中一个非常重要的特性,它可以帮助我们在程序运行时动态地获取类的信息,并且可以操作类的属性、方法和构造函数等。下面是一个简单的反射工具类: ```java import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class ReflectUtil { // 获取类的构造函数 public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameterTypes) throws NoSuchMethodException { return clazz.getConstructor(parameterTypes); } // 获取类的属性 public static Field getField(Class<?> clazz, String fieldName) throws NoSuchFieldException { return clazz.getDeclaredField(fieldName); } // 获取类的方法 public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) throws NoSuchMethodException { return clazz.getDeclaredMethod(methodName, parameterTypes); } // 创建对象 public static Object newInstance(Class<?> clazz) throws IllegalAccessException, InstantiationException { return clazz.newInstance(); } // 调用方法 public static Object invokeMethod(Method method, Object obj, Object... args) throws Exception { return method.invoke(obj, args); } // 设置属性值 public static void setFieldValue(Field field, Object obj, Object value) throws IllegalAccessException { field.setAccessible(true); field.set(obj, value); } // 获取属性值 public static Object getFieldValue(Field field, Object obj) throws IllegalAccessException { field.setAccessible(true); return field.get(obj); } } ``` 这个工具类提供了以下几个方法: - `getConstructor`:获取类的构造函数; - `getField`:获取类的属性; - `getMethod`:获取类的方法; - `newInstance`:创建类的实例; - `invokeMethod`:调用类的方法; - `setFieldValue`:设置类的属性值; - `getFieldValue`:获取类的属性值。 这些方法可以帮助我们在程序运行时动态地获取和操作类的信息,非常方便。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值