前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。
反射就是把java类中的各种成分映射成一个个的Java对象。
在加载类时,通过.java文件创建一个Class对象,一个类多次加载也只有一个Class对象。


Class 类的实例表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有N多的实例每个类都有该Class对象。(包括基本数据类型)
Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的defineClass 方法自动构造的。也就是这不需要我们自己去处理创建,JVM已经帮我们创建好了。
获取字节码文件对象(Class)的三种方法
- 通过 getClass(),object是一个引用变量,指向堆中对象
- 通过 类名.class
- 通过类的全限定名(即路径,包+"."+类名),调用静态方法Class.forName(String 路径)。需要抛出ClassNotFoundException异常
1 import javax.security.auth.callback.LanguageCallback;
2
3 public class TestFC {//测试反射机制
4 public static void main(String[] args) throws ClassNotFoundException {
5 Object object=new String("1234");//Object是所有类的父类,多态
6 Class c1=object.getClass();
7 System.out.println(c1);
8 object=new Student(520,1314);
9 c1=object.getClass();
10 System.out.println(c1);
11 System.out.println("----------1.通过getClass(),object是一个引用变量,指向堆中对象");
12
13 Class c2=String.class;
14 System.out.println(c2);
15 c2=Student.class;
16 System.out.println(c2);
17 System.out.println("----------2.通过类名.class");
18
19 Class c3=Class.forName("java.lang.String");//调用静态方法forName()
20 System.out.println(c3);
21 c3=Class.forName("my_test.Student");
22 System.out.println(c3);
23 System.out.println("----------3.通过类的全限定名。需要抛出ClassNotFoundException异常");
24 if(c1==c2 && c2==c3 && c1==c3)
25 System.out.println("Yes");//对象一样,证明获取的是同一个对象
26 }
27 }
28 class Student{
29 int id;
30 int age;
31 public Student(int id,int age) {
32 this.id=id;
33 this.age=age;
34 }
35 public void say() {
36 System.out.println("我是学生类的say方法");
37 }
38 }
输出:
class java.lang.String
class my_test.Student
----------1.通过getClass(),object是一个引用变量,指向堆中对象
class java.lang.String
class my_test.Student
----------2.通过类名.class
class java.lang.String
class my_test.Student
----------3.通过类的全限定名。需要抛出ClassNotFoundException异常
Yes
创建对象的方式
- 直接创建,不用反射
- 通过反射,获取构造器,再通过构造器对象调用newInstance()方法创建对象
Object stu1=new Student(33, 44);//不通过反射直接new出对象
//通过反射:Class对象的getConstructor方法拿到构造器。
Constructor constructor=c3.getConstructor(Integer.class,int.class);
//通过构造器的newInstance方法实例化并初始化变量
Object stu2=constructor.newInstance(96,85);
System.out.println(stu1);
System.out.println(stu2);//要抛出一大堆异常
输出:
my_test.Student@15db9742
my_test.Student@6d06d69c
通过此方法要抛出一大堆异常还有导入新的类包。添加如下:

package my_test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import javax.security.auth.callback.LanguageCallback;
public class TestFC {//测试反射机制
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Object object=new String("1234");//Object是所有类的父类,多态
Class c1=object.getClass();
System.out.println(c1);
object=new Student(520,1314);
c1=object.getClass();
System.out.println(c1);
System.out.println("----------1.通过getClass(),object是一个引用变量,指向堆中对象");
Class c2=String.class;
System.out.println(c2);
c2=Student.class;
System.out.println(c2);
System.out.println("----------2.通过类名.class");
Class c3=Class.forName("java.lang.String");//调用静态方法forName()
System.out.println(c3);
c3=Class.forName("my_test.Student");
System.out.println(c3);
System.out.println("----------3.通过类的全限定名。需要抛出ClassNotFoundException异常");
if(c1==c2 && c2==c3 && c1==c3)
System.out.println("Yes");//对象一样,证明获取的是同一个对象
Object stu1=new Student(33, 44);//不通过反射直接new出对象
//通过反射:Class对象的getConstructor方法拿到构造器。
Constructor constructor=c3.getConstructor(Integer.class,int.class);
//通过构造器的newInstance方法实例化并初始化变量
Object stu2=constructor.newInstance(96,85);
System.out.println(stu1);
System.out.println(stu2);//要抛出一大堆异常
}
}
class Student{
Integer id;
int age;
public Student(Integer id,int age) {
this.id=id;
this.age=age;
}
public void say() {
System.out.println("我是学生类的say方法");
}
}
Class常用方法
获取公共构造器 getConstructors()
获取所有构造器 getDeclaredConstructors()
获取该类对象 newInstance()
获取类名包含包路径 getName()
获取类名不包含包路径 getSimpleName()
获取类公共类型的所有属性 getFields()
获取类的所有属性 getDeclaredFields()
获取类公共类型的指定属性 getField(String name)
获取类全部类型的指定属性 getDeclaredField(String name)
获取类公共类型的方法 getMethods()
获取类的所有方法 getDeclaredMethods()
获得类的特定公共类型方法: getMethod(String name, Class[] parameterTypes)
获取内部类 getDeclaredClasses()
获取外部类 getDeclaringClass()
获取修饰符 getModifiers()
获取所在包 getPackage()
获取所实现的接口 getInterfaces()
参考:
https://blog.csdn.net/qq_36226453/article/details/82790375
https://blog.csdn.net/qq_44614710/article/details/86741226
