反射
反射(Reflection)是java程序开发语言的特征之一,它允许运行中的java对自身进行检查
反射就是把java类中的各种成分映射成一个个的java对象
加载的时候 : Class对象的由来是将.class文件读入内存,并为之创建一个Class对象
java反射机制,可以实现一下功能
- 在运行是判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
获取源头Class
所有类的对象其实都是Class的实例
获取类的Class对象
- Class.forName(“包名.类名”)
- 类.class
- 对象.getClass()
获取Class对象
Class是一切反射的源头
-
第一种对象.class
Source s=new Source();
Class<?>c1=s.getClass();
System.out.println(c1.getName()); -
第二种类.class
Class<?>c2=Source.class;
System.out.println(c2.getName()); -
第三种Class.forname
Class<?> c3=Class.forName(“com.shsxt.ref.simple.Source”);
System.out.println(c3.getName());
获取修饰符
获取修饰符,使用 getModifiers() 即可, Modifier 类提供了 static 方法和常量来解码类和成员访问修饰符
方法 :
int getModifiers() 返回此类或接口的Java语言修饰符,以整数编码。
代码 :
Class<?>clz=Class.forName(“com.shsxt.ref.simple.User”);
//获得修饰符
int n=clz.getModifiers();
//使用Modifier转换为相应的字符串
System.out.println(Modifier.toString(n));
父类与接口
方法:
类<?>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。
类<? super T> getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的直接超类 类 。
代码
//类<? super T> getSuperclass() 返回 类表示此所表示的实体(类,接口,基本类型或void)的直接超类 类 。
Class superClass = cls.getSuperclass();
System.out.println(superClass);
System.out.println(superClass==Object.class);
//类<?>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。
Class[] arr = cls.getInterfaces();
System.out.println(Arrays.toString(arr));
属性和方法
属性
获取所有属性(包括父类或接口) ,使用 Field 即可操作, Field 作为描述属性的对象
方法
字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。
字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。
字段 getDeclaredField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定声明字段。
字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。
学生类 :
package fanshe.field;
public class Student {
public Student(){
}
//**********字段*************//
public String name;
protected int age;
char sex;
private String phoneNum;
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", sex=" + sex
+ ", phoneNum=" + phoneNum + "]";
}
}
测试类
package fanshe.field;
import java.lang.reflect.Field;
public class Fields {
public static void main(String[] args) throws Exception {
//1.获取Class对象
Class stuClass = Class.forName("fanshe.field.Student");
//2.获取字段
System.out.println("************获取所有公有的字段********************");
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************获取所有的字段(包括私有、受保护、默认的)********************");
fieldArray = stuClass.getDeclaredFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("*************获取公有字段**并调用***********************************");
Field f = stuClass.getField("name");
System.out.println(f);
//获取一个对象
Object obj = stuClass.getConstructor().newInstance();//产生Student对象--》Student stu = new Student();
//为字段设置值
f.set(obj, "刘德华");//为Student对象中的name属性赋值--》stu.name = "刘德华"
//验证
Student stu = (Student)obj;
System.out.println("验证姓名:" + stu.name);
System.out.println("**************获取私有字段****并调用********************************");
f = stuClass.getDeclaredField("phoneNum");
System.out.println(f);
f.setAccessible(true);//解除私有限定
f.set(obj, "18888889999");
System.out.println("验证电话:" + stu);
}
}
方法
获取所有方法(包括父类或接口),使用 Method 即可。 Method 即作为描述方法的对象。
方法
方法 getDeclaredMethod(String name, 类<?>… parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定声明方法。
方法[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象表示的类或接口的所有已声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承的方法。
方法 getMethod(String name, 类<?>… parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定公共成员方法。
方法[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。
学生类
package fanshe.method;
public class Student {
//成员方法*//
public void show1(String s){
System.out.println("调用了:公有的,String参数的show1(): s = " + s);
}
protected void show2(){
System.out.pr