目录
1.反射机制的基本概念
*.动态创建对象和动态调用方法的机制(大部分框架就是用这个写的)
2.Class类(非常重要)
-
Class类非常重要,这是使用反射的基础。一定要熟练使用(****)
-
Class类是一个运行时类,他代表类在内存中的class对象
2.1Class类的获取
(1)获取基本数据类型的Class对象(重要)
-
语法: 数据类型.class
-
返回值: Class对象
Class c1 = String.class;
(2)使用对象的Class对象
-
语法: 对象/引用.getClass
-
返回值: Class对象
Class c2 = new Person().getClass();
-----------------------------------
Person p1 = new Person();
Class c3 = p1.getClass();
(3)获取包装类中的基本数据类型
-
语法: 包装类.TYPE
-
返回值: TYPE类型
TYPE type = Double.TYPE;
(4)利用Class类中的forName()方法
-
语法: Class.forName(String name) //name代表类的名称的全称(包名.类名)
-
返回值: Class对象
Class c4 = Class.forName("java.lang.String");
~全部测试代码
public class TestDemo2 {
public static void main(String[] args) {
//1.利用数据类型.class获取class对象 ******
Class c1 = String.class;
System.out.println("c1 = " + c1);
//2.利用对象.getclass获取class对象
/* Class c2 = new Person().getClass();
System.out.println("c2 =" +c2);*/
Person p1 = new Person();
Class c2 = p1.getClass();
//3.利用 包装类.TYPE获取基本数据类型
Class<Double> type = Double.TYPE;
System.out.println(type);
//4.利用Class类中的forname()方法(要写类的全程,包名.类名)
Class<?> c4 = null;
try {
c4 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("c4 =" +c4);
}
}
3.如何使用
3.1 在无法确定需要创建的对象类型时使用(动态创建对象)
-
在后期开发过程中,可能会出现无法确定需要的对象类型,但是我们又必须去创建对象,可以采用这种方式
.
构造类:Constructor(获取构造方法)
Class对象.getConstructor();**用来获取类的构造方法,非常重要**
方法:
getName()//获取构造方法的名称 getModifiers()//获取构造方法的访问修饰限定符 getParameterTypes()//获取构造方法的参数类型
1)无参构造
-
语法: Class对象.getConstructor();//可传参数获取有参构造
-
返回值: Constructor对象
Class c1 = Class.forName("Person");//获取类的Class对象
Constructor c = c1.getConstructor();//利用Class对象获取类的构造方法
Person p1 = c.newInstance();//利用无参构造方法创建实例
2)有参构造
-
语法: Class对象.getConstructor("构造方法的参数.class")
-
返回值: Constructor对象
Class c1 = Class.forName("Person");//获取类的Class对象
Constructor c = c1.getConstructor(String.class,int.class);//利用Class对象获取类的构造方法
Person p1 = c.newInstance("张飞",20);//利用有参构造方法创建实例
3)获取全部构造方法(在你无法确定构造方法的参数时)
-
语法: Class对象.getConstructors();
-
返回值: Constructor对象的数组
Class c1 = Class.forName("Person");//获取类的Class对象 Constructor[] cc = c1.getConstructors();//获取类中的全部构造方法
~测试代码
import java.lang.reflect.Constructor;
public class TestDemo3 {
public static void main(String[] args) throws Exception {
//获取无参构造方法,并且创建实例
Class c1 = Class.forName("Person");
Constructor c = c1.getConstructor();
System.out.println(c.newInstance());
//获取有参构造(知道参数类型的前提)(方法传入的是Class对象)
Constructor cc = c1.getConstructor(String.class, int.class);
System.out.println(cc.newInstance("zhangfei", 20));
//获取全部的构造方法
Constructor[] constructors = c1.getConstructors();
for(Constructor tmp : constructors) {
System.out.println(tmp.getName());//获取构造方法的名字
System.out.println(tmp.getModifiers());//获取构造方法的访问修饰限定符
Class[] parameterTypes = tmp.getParameterTypes();//获取方法的参数类型
for(Class ccc : parameterTypes) {
System.out.println(ccc);
}
}
}
}
3.2 获取类中的成员信息(暴力反射)
Field类
Class对象.getDeclaredField(变量名称)
1)获取单个成员变量(修改)
-
语法:Class对象.getDeclaredField(“变量名称”)
-
返回值: Field对象(可以看作是一种方式)
Person p1 = new Person("zhangfei",20);//创建一个Person对象,便于测试
Class c1 = Class.forName("Person");//获取Person类的Class对象
Field name = c1.getDeclaredField("name");//利用Class对象获取Person类的name变量
Object o = name.get(p1);//获取p1实例的name信息
name.set(p1,"guanyu");//修改p1中的name变量
/* 可以把Field看作是一种方式
假设Person是一张身份证,而你需要等级身份证的姓名,你就雇了一个人去给你念每张身份证的姓名,你 只需要把身份证扔给他,他就能告诉你姓名
这里的Field就是你雇佣的那个人,在使用时你只需要把身份证(对象实例)扔给他就行了,让他给你返回 姓名
*/
2)获取全部的成员变量
-
语法:Class对象.getDeclaredFields()
-
返回值: Field对象数组
Class c1 = Class.forName("Person");//获取Class对象
Field[] declaredFields = c1.getDeclaredFields();//获取Person类里的所有成员变量
3.3获取类中的成员方法
Method类
-
此类用来接收类中的成员方法
-
Invoke()//调用获取到的方法
1)单个成员方法
-
语法: Class对象.getMethod(”方法的名称“)
-
返回值: Method对象
Person p1 = new Person();//用于测试
Class c1 = Class.forName("Person");//获取Class对象
Method m1 = c1.getMethod("getName");//获取getName方法
Object invoke = m1.invoke(p1);//调用getname方法
2)全部成员方法
-
语法: Class对象.gerMethods()
-
返回值 : Method数组
Person p1 = new Person();//获取Class对象
Method[] methods = c1.getMethods();//获取全部的成员方法
for(Method m1 : methods) {
System.out.println(m1.getName());//获取成员方法的名称
System.out.println(m1.getParameterTypes());
System.out.println(m1.getModifiers());
}