反射就是java自我管理这些类、对象的机制
反射的作用:
可以通过反射机制发现对象类型,发现类型的方法,属性,构造器,可以创建对象,并访问其中的属性,方法等
反射机制中使用的几个重要的类:
Class:描述类的类
Method:描述方法的类
Field:描述属性的类
Constructor:描述构造方法的类
Class加载:
类加载到内存:JAVA将磁盘类文件加载到内存中,为一个对象(实例),这个对象是Class的实例.
xxx.class ==> Class实例,这个实例描述xxx类
Class类实例代表java中的类
获取Class类实例(获取某个java类描述)
获取描述基本类型的Class实例
Class class=int.class;
long.class;
double.class;.......
获取引用类型的Class实例
Class cla=String.class; 类名.class
Class cla=Class.forName("java.lang.String");
Class cla="abc".getClass(); 对象.getClass()
通过Class的实例,可以获取这个实例所描述的java类都定义了那些属性,方法和构造器
=================================================================================================
示例代码:
package com.szy.day12_reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
/**
* java反射
* Class类应用
* @author soft1
*
*/
public class ClassDemo {
public static void main(String[] args) {
//reflect(new Card(Card.HEART,Card.TEN));
/* ArrayList al=new ArrayList();
reflect(al);*/
/*
Object obj=create("java.util.ArrayList");
System.out.println(obj);
reflect(obj);*/
Person person=new Person();
String name=person.name;
System.out.println("名字:"+name);
person.sayName();
int a= person.add(4, 4);
System.out.println(a);
System.out.println("=====================================");
Object obj=create("com.szy.day12_reflect.Person");
Object name1=getFieldValue(obj, "age");
System.out.println("名字:"+name1);
call(obj,"sayName",new Class[]{},new Object[]{});
Object returnValue=call(obj,"add",new Class[]{int.class,int.class},new Object[]{4,4});
System.out.println(returnValue);
}
/**
* 根据类的完整名称(包路径.类名),创建该类的实例
*
* 1:根据类名创建用于描述此类的Class实例
* 2:通过Class实例的newInstance()方法创建类的实例
* 3:返回这个实例
* @param pack
* @return
*/
public static Object create(String pack){
try {
//1
/**
* java加载类使用"懒惰加载方式"
* 内部加载过程:
* 1.根据className从环境变量classpath中寻找类
* 2.找到后读取此类的.class文件并转换为Class一个实例
* 3.将Class实例加载入内存
*
* 懒惰方式加载:
* 即检查内存中是否存在此类的Class实例,若有就直接使用,若没有则读取.class文件
* Class类的实例,对于描述的类来讲,是唯一的
*/
Class cla=Class.forName(pack);
System.out.println("准备创建"+cla.getName()+"的实例");
//2
Object o=cla.newInstance();
//3
return o;
} catch (Exception e) {
throw new RuntimeException("加载出错了!",e);
}
}
/**
* 根据给定的对象,打印这个对象所属类都定义了那些属性方法构造器
*
* 1.获取用于描述obj所属类的Class的实例
* 2.通过Class实例,获取obj所属类定义的属性
* 3.通过Class实例,获取obj所属类定义的方法
* 4.通过Class实例,获取obj所属类定义的构造器
* @param obj
*/
public static void reflect(Object obj){
//1
Class cls=obj.getClass();
//打印obj所属类的名字
System.out.println("类:"+cls.getName());
//2
Field fields[]=cls.getFields();
System.out.println("属性:");
for(Field field:fields){
System.out.println(field.getType()+ //属性的类型
":"+
field.getName() //属性的名字
);
}
//3
Method methods[]=cls.getMethods();
System.out.println("方法:");
for(Method method:methods){
System.out.println(
method.getReturnType()+//方法类型
" "+
method.getName()+ //方法名称
" "+
Arrays.toString(method.getParameterAnnotations())
);
}
//4
Constructor constructor[]=cls.getConstructors();
System.out.println("构造器:");
for(Constructor c: constructor){
System.out.println(
c.getName()+" "//构造器的名字
+Arrays.toString(c.getParameterTypes())
);
}
}
/**
* 根据给定的对象,属性名获取这个属性的值
* @param obj
* @param fieldName
* @return
*/
public static Object getFieldValue(Object obj,String fieldName){
try {
/*
* 获取obj所属类的描述类Class的实例
*/
Class cla=obj.getClass();
/*
* 根据Class实例获取指定名字的属性定义Field实例
*/
Field field=cla.getDeclaredField(fieldName);
/*
* 根据属性定义Field实例获取此类的具体对象的这个属性的值
*/
Object value=field.get(obj);
/*
* 返回属性值
*/
return value;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("出错了");
}
}
/**
* 给定对象,方法名,参数列表以及实际参数,利用反射机制调用方法
* @param obj 给定的对象
* @param methodName 给定的方法名
* @param paramType 给定的参数列表
* @param paramValue 实际参数
* @return 条用方法后返回的结果,若该方法定义的返回值类型为void,那么反射调用方法后返回值为null
*/
public static Object call(Object obj,String methodName,Class[] paramType,Object[] paramValue){
try{
//获取用于描述obj所属类的Class实例
Class cls=obj.getClass();
//根据方法明获取用于描述该方法的method实例
Method method=cls.getDeclaredMethod(methodName, paramType);
/**
* 使用Method的invoke()方法,就相当于调用了Method所描述的那个方法,invoke()方法的返回值就是调用
* 了实际方法后该方法的返回值
*/
Object returnValue=method.invoke(obj, paramValue);
/**
* 若当前调用的方法的返回值为void时,invoke()返回的结果为null
*/
return returnValue;
}catch(Exception e){
throw new RuntimeException("出错了");
}
}
}
class Person{
String name="黄海";
int age=1;
public void sayName(){
System.out.println("我的名字是:"+name);
}
public int add(int a,int b){
return a+b;
}
}