什么是类反射呢?
我查了API对他的描述如下
Class 类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也表示为 Class 对象
我的理解呢 就是一个描述类的类。举个例子:写一个Person的类,他可以描述张三,李四等人吧。 写一个Car的类,他可以用来描述三轮,卡车,汽车。 类反射就是一个特殊的类可以用来描述其他所有类的类。
关系 如图:
明白了类反射,我们就来学学他有什么用
这是我们有通过类反射的类的代码如下
public class UserModel implements Serializable{
private static final long serialVersionUID = 1L;
private String uuid;//用户id
private String name;//用户名
private int type;//用户类型
private String pwd;
public UserModel(){
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((uuid == null) ? 0 : uuid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserModel other = (UserModel) obj;
if (uuid == null) {
if (other.uuid != null)
return false;
} else if (!uuid.equals(other.uuid))
return false;
return true;
}
@Override
public String toString() {
return uuid + ", " + name + ", " + type;
}
}
package dage.hello.Demo1;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectionHelloWorld {
public static void main(String[] args) {
try {
// Field 就是一个类,专门用来反映成员变量信息的(像 private ,public,final,static ,)
//c.getFields()返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段
//c.getDeclaredFields()返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。(包括私有的)
// 获得类反射时, 用Class.forName();方法时,一定要用类全名
Class c = Class.forName("dage.hello.Demo1.UserModel");
// 那么有什么用呢? 类反射 里面的一个类,干什么用的 输出一下就知道了
Field fs2[] = c.getFields();
Field fs[]=c.getDeclaredFields();
System.out.println("--------Field----------");
for(Field f:fs){
System.out.println(f.toString());
System.out.println();
}
// Constructor 反映构造方法的类
// c.getDeclaredConstructors() 可以拿到所有 Class 对象的构造方法
// c.getConstructors() 可以拿到公共 Class 对象的构造方法
System.out.println("-----Constructor-----");
Constructor cts[]=c.getDeclaredConstructors();
for(Constructor ct:cts){
System.out.println(ct);
}
// Method 反映Class方法的类
// c.getDeclaredMethods(); 可以拿到所有 Class 对象的方法
// c.getMethods(); 可以拿到公共 Class 对象的方法
System.out.println("----Method-----");
Method ms []=c.getDeclaredMethods();
for(Method m:ms){
System.out.println(m);
}
//Annotation[] getDeclaredAnnotations() 返回直接存在于此元素上的所有注释。
System.out.println("----Annotation-----");
Annotation[] as=c.getDeclaredAnnotations();
for(Annotation a:as){
System.out.println(a);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
结果;查到了UserModel里面的方法 成员变量等
那么,有哪几种可以获得Class 的方法呢?
//法1:通过对象--- 对象.getClass() 来获取c (一个Class对象)
@Test
public void get1(){
Person p = new Person("Jack",22);
Class c = p.getClass();//来自Object的方法
}
//法2:通过类(类型)----任何数据类型(包括基本数据类型)都有一个静态的属性class, 它就是c (一个Class对象)
@Test
public void get2(){
Class c = Person.class;
Class c2 = int.class;
}
//法3(能够实现解耦):通过字符串(类的全名)---- Class.forName( str )
@Test
public void get3(){
try {
Class c = Class.forName("cn.hncu.reflect.one.Person");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
接下来就是类反射的一些方法学习
package cn.hncu.reflect.two;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class ReflectDecompose{
private static final String clsName = "cn.hncu.reflect.two.UserModel";
// 获取类中所有方法(非构造方法)的信息
@Test
public void demo1() throws Exception{
Class clazz = Class.forName(clsName);
//Method ms[] = clazz.getDeclaredMethods();//获取当前类中声明的所有方法,包括私有的 ---不包括父类中的方法
Method ms[] = clazz.getMethods();//获取当前类及其父类的所有public方法(不包括访问权限以外的方法)---相当于:UserModel user=new UserModel(); 该user对象在此处所能调用的那些方法
for(Method m:ms){
System.out.println(m.toGenericString());
System.out.println("name:"+ m.getName());//方法名
System.out.println("DeclaringClass:"+ m.getDeclaringClass());//方法是在哪个类中声明的
//方法的参数类型列表
Class paramTypes[] = m.getParameterTypes();
for(int i=0;i<paramTypes.length;i++){
Class c = paramTypes[i];
System.out.println("param"+i+":"+c);
}
//方法所抛出的异常列表
Class exceps[]= m.getExceptionTypes();
for(int i=0;i<exceps.length;i++){
Class c = exceps[i];
System.out.println("excep"+i+":"+c);
}
//返回类型
System.out.println("returnType:"+ m.getReturnType());
//修饰符(private static final synchronized)
int modifier = m.getModifiers();
System.out.println("修饰符:"+ Modifier.toString(modifier));
System.out.println("-----------");
}
}
// 获取类中所有构造方法的信息 ---提醒一个知识点: 子类是不会继承父类 构造方法(构造器) 的
@Test
public void demo2() throws Exception{
Class clazz = Class.forName(clsName);
//Constructor cons[] = clazz.getDeclaredConstructors();//获取当前类中声明的所有构造器,包括私有的
Constructor cons[] = clazz.getConstructors();//获取当前类的所有public的构造器(不包括访问权限以外的构造器)---相当于:在此处所能调用的那些构造器
for(Constructor con:cons){
System.out.println(con.toGenericString());
System.out.println("name:"+ con.getName());//方法名
System.out.println("DeclaringClass:"+ con.getDeclaringClass());//方法是在哪个类中声明的
//方法的参数类型列表
Class paramTypes[] = con.getParameterTypes();
for(int i=0;i<paramTypes.length;i++){
Class c = paramTypes[i];
System.out.println("param"+i+":"+c);
}
//方法所抛出的异常列表
Class exceps[]= con.getExceptionTypes();
for(int i=0;i<exceps.length;i++){
Class c = exceps[i];
System.out.println("excep"+i+":"+c);
}
//修饰符(private static final synchronized)
int modifier = con.getModifiers();
System.out.println("修饰符:"+ Modifier.toString(modifier));
System.out.println("-----------");
}
}
// 获取类中所有属性(字段或变量)的信息
@Test
public void demo3() throws Exception{
Class clazz = Class.forName(clsName);
//Field flds[] = clazz.getDeclaredFields();//获取当前类中声明的所有变量,包括私有的
Field flds[] = clazz.getFields();//获取当前类及其父类的所有public的变量(包括访问权限允许的所有变量)---相当于:在此处所能调用的那些变量
for(Field fld:flds){
System.out.println(fld.toGenericString());
System.out.println("name:"+ fld.getName());//变量名
System.out.println("DeclaringClass:"+ fld.getDeclaringClass());//变量是在哪个类中声明的
System.out.println("Type:"+ fld.getType() );//变量类型
//修饰符(private static final)
int modifier = fld.getModifiers();
System.out.println("修饰符:"+ Modifier.toString(modifier));
System.out.println("-----------");
}
}
}
class AA {
public int a=5;
protected double x=1;
public void aa(int a, double b, String s) {
}
}