Java基础--反射

反射的基石–>Class类

  • Java程序中的各个Java类属于同一类事物,描述这一类事物的Java类名就是Class.
  • 众多的人用什么类表示?众多的Java类用一个什么类表示?
  • 人—>Person
  • 类—>Class

那么,Person类代表张三李四,实实在在的对象.那么Class类的对象是什么呢?

  • 对应各个类在内存中的字节码,例如Person类的字节码,ArrayList类的字节码等.
  • 一个类被类加载器加载到内存,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不用的.
    用于描述一类事物的共性,该类事物有什么属性,没有什么属性.Java中各个类属于同一类事物,这个类就是Class.

Person p1 = new Person();
Student s2 = new Student ();

Class cls1 = 字节码(Person.class);
Class cls2 = 字节码(Student.class);

p1.getClass == Class.forName(“Person”)==Person.class; 得到字节码的方式三种 true
Class.forName作用:返回字节码.第一种:曾经被加载过的字节码:直接返回.没有加载过,用类加载器加载,返回.
主要使用Class.forName(),因为在写源程序的时候还不知道类的名字,把forName()里面定义一个变量,通过字符串传进来.这个字符串包含了一个类的名字.
int.class = Integer.TYPE;
数组类型的Class不是基本数据类型,Class.isArray()判断数据类型是否为数组
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int[],void…

/**
 * 
 */
package reflect;

/**
 * @author LYG
 *
 */
public class ReflectDemo2 {

	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		// TODO Auto-generated method stub
		String str1 = new String("abc");
		Integer i = 3;
		int i1 = 3;
		Class<? extends String> cls1 = str1.getClass();
		Class<String> cls2 = String.class;
		Class<?> cls3 = Class.forName("java.lang.String");
		
		System.out.println(cls1==cls2);
		System.out.println(cls1==cls3);
		System.out.println("String是基本类型吗:"+cls1.isPrimitive());
		System.out.println("Integer是基本类型吗:"+i.getClass().isPrimitive());
		System.out.println(int.class.isPrimitive());
		System.out.println(int.class == Integer.class);
		System.out.println(int.class == Integer.TYPE);
		System.out.println(double.class == Double.TYPE);
		System.out.println(void.class == Void.TYPE);
		//TYPE代表所包装的基本数据类型
		System.out.println(int[].class.newInstance());
		System.out.println(cls1.newInstance());
	}

}

运行结果:
cls1cls2:true
cls1
cls3:true
String是基本类型吗:false
Integer是基本类型吗:false
int.class.isPrimitive():true
int.class == Integer.class:false
int.class == Integer.TYPE:true
double.class == Double.TYPE:true
void.class == Void.TYPE:true

反射就是把Java类中的各种成分映射成相应的Java类,例如,一个Java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造函数,包等等信息.这些信息也用一个个的Java类表示,就像汽车是一个类,汽车中的发动机,变速箱也是一个个的类.表示Java类的Class类显然要提供一系列的方法来获得其中的变量,方法,构造函数,修饰符,包等信息.这些信息就是相应类的实例对象来表示,他们是Field,Method,Constructor,Package等等.
一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示.通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用呢?怎么用呢?这就是学习和应用反射的要点.

Constructor类:代表某个类中的一个构造方法.
得到某各类所有的构造方法:
返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

Constructor con = String.class.getConstructor(StringBuffer.class);
String s = (String) con.newInstance(new StringBuffer("aaa"));
System. out.println(s );

编译器不知道con属于哪个类的字节码,因此类型不确定,要强转才可以使用.

class–>constructor–>newInstance
class–>newInstance 这个方法调用的是空参构造方法!

Class类放在 java.lang包中。java.lang.reflect包是关于反射的包。用Class类实例化其他类的对象,能够被Class类实例化的类的构造函数要被public修饰,暴露出去。
   用Class类实例化其他类的对象的步骤:
  1,用Class类中的静态方法forName(类名)返回一个Class类对象,就是定义需要操作哪一个类的字节码文件
  2,用getConstructor(构造函数参数列表的class类型)方法返回一个Constructor对象,这也是确定了该类的某个构造函数。
  3,用newInstance(构造函数参数列表的实例对象)方法返回一个Object对象。
      其中2和3步骤中的括号里面构造函数的参数列表需要一致,不同的只是步骤2括号里面的是构造函数参数列表的class类型,步骤3里面的是构造函数参数列表的实例对象

Class类里面也有自己的newInstance方法:
1,先从内部获取不带参数的构造函数,
2,然后可以用这个构造函数建立实例对象,举例:
Stringstr=(String)Class.forName(“java.lang.String”).newInstance() ;

当然,通过Class来获取其他类的所有构造函数:

     Class<?> class=Class.forName("Person"); 
     //Class类和Constructor类最好写上泛型限定
     Constructor<?>  con[]=    cla.getConstructors();

利用反射获取类的成员变量
确定需要操作的类的字节码文件
调用getField方法获取类中的public修饰的成员变量,返回一个Field类对象
这里注意:是类中的成员变量,不是对象的变量,
要注意是否有初始化。
getDeclaredField方法则是无论公有还是私有变量可以获取,推荐使用该方法。
用get方法确定该变量在哪一个对象上的所对应的值,该方法用于public修饰的变量上,
如果先用setAccessible(true)方法设定好可以暴力反射,
那么再用get方法可以暴力获取该变量在哪一个对象上的所对应的值。
注意:get 返回的是Object类型

利用反射获取类的方法
1,确定要被操作的类的字节码
2,用getMethod(方法名,参数列表的.class形式) 方法获取该方法
getMethod方法返回的是一个Method类的变量
3,调用Method类中的invoke(类的实例对象,实际参数)方法
来获取Method类对象对应的该方法在类的对象上对应的结果

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值