Object类中有一个getClass()方法,是用于获取当前对象所述的类信息,返回Class对象。这个方法在Class类中是典型的使用。
使用反射的起点总是java.lang.Class 实例。
什么是反射 反射机制指的是程序在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。至于为什么名字取名叫反射,我想的等我写完就知道为什么了。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
!
Class类的使用 怎么理解Class类呢,在Java里,万物皆对象(在Java中只有两个东西不是对象,一个是静态成员,一个是基本数据类型,但是基本数据类型也有他的包装类来弥补它),一个类也可以是一个对象,既然是对象,那么必然这个对象就有类型。比如我们声明一个对象的引用变量的时候,这个引用变量的类型就是类类型,比如A a=new A();
,这时候a的类型就是类类型。那么类作为对象的时候,class类就是它的类型,即类是java.lang.Class 实例对象。
一般一个类的对象怎么表示呢,我们用A a=new A();
这样就表示出来了,那么这个A类本身也是一个Class类的一个对象,那么这个类怎么表示呢,这个类就不能new出来了,
因为他的构造方法是私有的private Class(){ },在类的外部是不能直接创建的,是由JVM创建的,那么我们怎么表示这个实例对象呢。三种方法:
- Class c1=A.class;
这种方法也是在告诉我们任何一个类都有一个隐含的静态成员变量class。
- 已知该类的对象通过getClass(),Class c2=a.getClass();
官方对于c1,c2是这么说的,表示了A类的类类型(class type),万事万物皆对象,类也是对象,是class的实例对象,这个对象我们成为该类的类类型。这时候c1等于c2的,c1和c2都代表了A类的类类型,一个类只能有一个类类型。
- Class c3=null;
c3=Class.forName(“类名全称”);
c1c2c3
动态加载 动态加载:在程序运行时才会加载class文件。静态加载:在程序编译期间去加载class文件。class.forName()是在运行期间加载的。在编译时刻加载的话需要把所有运行时可能用到的类都加载,如果没有,就会报错。但在实际中我们需要用到那个类就去加载哪个类,这就需要在运行时去加载需要用到的类,这就不会报错了。
反射可以通过类类型去获取类的方法的信息,成员的信息。
方法反射的基本操作 【Java自学之反射——自学笔记】两个步骤
- 获取某个方法:方法的名称和方法的参数列表才能唯一确定一个方法。
- 方法反射的操作:method.invoke(对象,参数列表);
package com.ann.test;
import java.lang.reflect.Method;
public class MethodDemo1 { public static void main(String[] args) {
//要获取print(int,int)方法 1.要获取一个方法就是获取类的信息,获取累的信息首要获取类的类类型
A a1 = new A();
Class c = a1.getClass();
/*2.获取方法 名称和参数列表来决定
*getMthod获取的是public的方法
*getDelcaredMethod是获取自己声明的方法
*/
try {
//c.getMethod("print", new Class[]{int.class,int.class});
Method m=c.getMethod("print", int.class,int.class);
//方法的反射操作
//a1.print(10,20);
方法的反射操作是用m对象来进行方法调用和a1.print调用的效果一样的
//方法如果没有返回值返回null,有返回值返回具体的返回值
Object o=m.invoke(a1, new Object[]{10,20});
System.out.println("--------");
Method m1 = c.getMethod("print", String.class,String.class);
//用方法进行反射操作
//a1.print("hello","WORLD");
o = m1.invoke(a1,"hello","WORLD");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class A{
public void print(int a,int b) {
System.out.println(a+b);
}
public void print(String a,String b) {
System.out.println(a.toUpperCase()+","+b.toLowerCase());
}
}
**至于为什么叫反射,是因为反射的本质就是得到class对象后,反向获取class对象的对象的信息**
推荐阅读
- java IO流相关的类的分类和总结
- java 数组声明定义 数组内存分配 数组初始化 数组引用 数组的遍历
- Java中构造器内部的多态方法的行为
- 多态性之编译期多态和运行期多态(JAVA版)
- Java向下转型的意义与塑型的三个方面
- Java自学Math类——自学笔记
- Java自学笔记|接口之间的继承
- Java自学笔记|System.in与System.out(标准输入与输出)详解
- Java自学之break与标号一同使用——自学笔记