反射

一提到反射,那么就要想到是运行时的事,而不是编译时的事.

在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答案是肯定的。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制

Java 反射机制主要提供了以下功能:(注意都是运行时的)

•在运行时判断任意一个对象所属的类。
•在运行时构造任意一个类的对象。
•在运行时判断任意一个类所具有的成员变量和方法。
•在运行时调用任意一个对象的方法

在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中
–Class类:代表一个类。
–Field 类:代表类的成员变量(成员变量也称为类的属性)。
–Method类:代表类的方法。
–Constructor 类:代表类的构造方法。
–Array类:提供了动态创建数组,以及访问数组的元素的静态方法

Java中,无论生成某个类的多少个对象,这些对象都会对应于同一个Class对象,如Integer生成很多个对象,那这些对象都会对应于Integer这个类所对应的Class对象

Class是Reflection起源。针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由后者唤起为数十多个的Reflection APIs

获取某个类或某个对象所对应的Class对象的常用的3种方式:
a) 使用Class类的静态方法forName:Class.forName(“java.lang.String”);
b) 使用类的.class语法:String.class;
c) 使用对象的getClass()方法:String s = “aa”; Class<?> clazz = s.getClass();


若想通过类的不带参数的构造方法来生成对象,我们有两种方式:
a) 先获得Class对象,然后通过该Class对象的newInstance()方法直接生成即可:
Class<?> classType = String.class;
Object obj = classType.newInstance();
b) 先获得Class对象,然后通过该对象获得对应的Constructor对象,再通过该Constructor对象的newInstance()方法生成:
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{});
Object obj = cons.newInstance(new Object[]{});
若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:
Class<?> classType = Customer.class;
Constructor cons = classType.getConstructor(new Class[]{String.class, int.class});
Object obj = cons.newInstance(new Object[]{“hello”, 3});

 

对于Method:

得到它的方法:那么就要得到它的那个方法所对应的Method对象.getMethod(,)这个方法可以唯一的确定你是调用那个方法,由它后面的那个参数决定.前面那个是方法名,后面那个是方法的参数类型的class,代码如下:

Class<?> classType = InvokeTester.class;

  Object invokeTester = classType.newInstance();

  // System.out.println(invokeTester instanceof InvokeTester);

  Method addMethod = classType.getMethod("add", new Class[] { int.class, int.class });

Object result = addMethod.invoke(invokeTester, new Object[]{1, 2});

注意反射总是返回Object类型及其子类型,原生数据类型则是它的包装类.

通过反射可以在类的外边调用类的私有方法.
method.setAccess...方法,这个方法是它的父类的方法.它压制JAVA对访问修饰符的检查.

getDeclaredMethod与getMethod方法的区别是前者连private的成员都可以得到,而后者只得到public的.

Field的使用跟Method的是大同小异的

 

注意的是:Integer.TYPE返回的是它的原生数据类型的Class对象,Integer.class才是真正返回的是Integer的Class对象.

 

数组本身也是对象,Array.newInstance()可以生成一个数组对象.

public class ArrayTester2
{
 public static void main(String[] args)
 {
  int[] dims = new int[] { 5, 10, 15 };//这个数组是代表是维度.

  Object array = Array.newInstance(Integer.TYPE, dims);//创建了一个三维数组,长,宽,高分别为5,10,15.
  
  System.out.println(array instanceof int[][][]);

  Object arrayObj = Array.get(array, 3);

  arrayObj = Array.get(arrayObj, 5);

  Array.setInt(arrayObj, 10, 37);

  int[][][] arrayCast = (int[][][]) array;

  System.out.println(arrayCast[3][5][10]);//打印出37来

  // System.out.println(Integer.TYPE);
  // System.out.println(Integer.class);

 }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yjsuge

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值