目录
一、Class
1.概念:
Class的实例化对象就是一个运行时类。此外,实例还包括接口、基本数据类型、数组、枚举、注解、void ,加载到内存中的运行时类,会缓存一定的时间,在此时间内,我们可以通过不同的方式去获取该运行类。
2.获取Class对象
四种方式:代码如下
@Test
//Class实例化
public void test() throws ClassNotFoundException {
//方式一:调用运行时类的属性
Class<Person> clazz1=Person.class;
System.out.println(clazz1);
//方式二:通过运行时类的对象,代用getClass()
Person p1=new Person();
Class clazz2= p1.getClass();
System.out.println(clazz2);
//方式三:调用Class的静态方法,forname(String classpath)
Class clazz3=Class.forName("reflection.Person");
System.out.println(clazz3);
//方式四:使用类的加载器ClassLoader(了解即可)
ClassLoader classloader=demo1.class.getClassLoader();
Class clazz4= classloader.loadClass("reflection.Person");
System.out.println(clazz4);
}
3.创建运行时类的对象
@Test
public void test() throws InstantiationException, IllegalAccessException {
Class<Person> clazz= Person.class;
Person p1=clazz.newInstance();
System.out.println(p1);
}
二、获取运行时类的属性结构
package reflectionexample;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/*获取运行时类的属性结构*/
public class FieldTest {
@Test
public void test1(){
Class clazz= Person.class;
Field[]fields= clazz.getFields();//获取当前运行类及父类中声明为public的属性
for (Field field : fields) {
System.out.println(field);
}
System.out.println();
Field[]fields1=clazz.getDeclaredFields();//获取当前类中声明的所有属性(不包含父类中声明的属性)
for (Field field : fields1) {
System.out.println(field);
}
}
//权限修饰符 变量名 数据类型
@Test
public void test2(){
Class clazz=Person.class;
Field[]fields=clazz.getDeclaredFields();
for (Field field : fields) {
//权限修饰符
int modifiers = field.getModifiers();
System.out.print(Modifier.toString(modifiers)+"\t");
//变量名
String name=field.getName();
System.out.print(name+"\t");
//数据类型
Class type = field.getType();
System.out.println(type.getName()+"\t");
}
}
}
三、获取运行时类的方法
package reflectionexample;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class methodTEst {
//获取运行时类的方法
@Test
public void test1(){
Class clazz=Person.class;
Method []methods=clazz.getMethods();//获取当前运行时类和父类中声明的Public方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("*****************************************************************");
Method []methods2=clazz.getDeclaredMethods();//获取当前运行时类的所有方法,不包括父类中声明的方法
for (Method method : methods2) {
System.out.println(method);
}
}
//获取运行时类的方法极其内部结构
@Test
public void test2(){
Class clazz=Person.class;
Method[]methods=clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
//获取方法声明的注解
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//权限修饰符
System.out.print(Modifier.toString(method.getModifiers())+"\t");
//返回值类型
System.out.print(method.getReturnType().getName()+"\t");
//方法名
System.out.println(method.getName());
//形参列表
Class [] parameterTypes = method.getParameterTypes();
if(!(parameterTypes.length==0&¶meterTypes==null))
for (Class parameterType : parameterTypes) {
System.out.print(parameterType.getName()+"\t");
}
//异常
Class[] exceptionTypes = method.getExceptionTypes();
if(exceptionTypes.length>0){
for (Class exceptionType : exceptionTypes) {
System.out.println(exceptionType.getName());
}
}
}
}
}
四、获取运行时类的其他属性
package reflectionexample;
import com.sun.security.jgss.GSSUtil;
import org.junit.Test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class OtherTest {
//获取构造器
@Test
public void test(){
Class clazz=Person.class;
Constructor[] constructors = clazz.getConstructors();//获取当前运行时类中声明为public的构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("****************************************************");
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();//获取当前运行时类中声明的所有的构造器
for (Constructor de : declaredConstructors) {
System.out.println(de);
}
}
//获取运行时类的父类
@Test
public void test02(){
Class clazz=Person.class;
Class superclass = clazz.getSuperclass();
System.out.println(superclass);
}
//获取运行时类带泛型的父类
@Test
public void test03(){
Class clazz=Person.class;
Type genericSuperclass = clazz.getGenericSuperclass();
System.out.println(genericSuperclass);
}
//获取运行时类带泛型的父类的泛型
@Test
public void test04(){
Class clazz=Person.class;
Type genericSuperclass = clazz.getGenericSuperclass();
ParameterizedType parameterizedType=(ParameterizedType)genericSuperclass;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
System.out.println(actualTypeArguments[0].getTypeName());
}
//获取运行时类及父类的实现的接口
@Test
public void test05(){
Class clazz=Person.class;
Class[] interfaces = clazz.getInterfaces();
for (Class anInterface : interfaces) {
System.out.println(anInterface);
}
System.out.println("***********************");
Class[] interfaces1 = clazz.getSuperclass().getInterfaces();
for (Class aClass : interfaces1) {
System.out.println(aClass);
}
}
//获取运行时类所在的包
@Test
public void test06(){
Class clazz=Person.class;
Package aPackage = clazz.getPackage();
System.out.println(aPackage);
}
//获取运行时类的注解
@Test
public void test07(){
Class clazz=Person.class;
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
}
}
五、获取指定运行时类的属性和方法
package reflectionexample;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
//调用运行时类中指定的结构:属性 方法 构造器
public class UseMetodsTest {
//获取指定的属性
//方式1
@Test
public void test01() throws Exception {
Class clazz=Person.class;
Person p=(Person)clazz.newInstance();
Field weight = clazz.getField("weight");//该方式只能获取权限为Public的属性
weight.set(p,101);//需要先指定对象,然后再赋值
Object o = weight.get(p);
System.out.println((int)o);
}
//方式2
@Test
public void test02() throws Exception {
Class <Person>clazz= Person.class;
Person p=clazz.newInstance();
Field name = clazz.getDeclaredField("name");//获取运行时类的指定变量名的属性
name.setAccessible(true);//保证当前属性是可以访问的
name.set(p,"ingram");
Object o = name.get(p);
System.out.println((String)o);
}
//操作运行时类的指定的方法
@Test
public void test03() throws Exception {
Class<Person>clazz=Person.class;
Person p=clazz.newInstance();
Method show = clazz.getDeclaredMethod("show", String.class);//获取方法
show.setAccessible(true);//保证当前方法是可以访问的
Object nation=show.invoke(p,"China");//返回值是show方法的返回值
System.out.println(nation);
//访问静态方法
Method out = clazz.getDeclaredMethod("miss");
out.setAccessible(true);
out.invoke(Person.class);
}
}
六、获取运行时类指定的构造器
package reflectionexample;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
//获取运行时类的构造器
public class UseConstructorTest {
@Test
public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class clazz=Person.class;
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
Person o = (Person) declaredConstructor.newInstance("蒲汶文", 21);
System.out.println(o);
}
}
七、动态代理模式
即不用重复写多个代理类来实现被代理类的方法,只需创建一个代理类来调用各个被代理类的方法即可。
package DynamicProxy;
//动态代理的举例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Human{
String getbelief();
void eat(String food);
}
//被代理类
class Superman implements Human{
@Override
public String getbelief() {
return "I believe I can fly! ";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃"+food);
}
}
class ProxyFactory{
//此方法用于返回一个代理类对象
public static Object getProxyInstance(Object obj){//obj是被代理类对象
myInterface myInterface=new myInterface();
myInterface.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),myInterface);
}
}
class myInterface implements InvocationHandler{
private Object obj;
public void bind(Object obj){
this.obj=obj;
}
//当我们通过代理类对象调用方法a时,就会自动调用如下方法:invoke()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method即为代理类对象调用的方法,此方法也就作为了被代理对象要调用的方法
Object invoke = method.invoke(obj, args);
return invoke;
}
}
public class Proxytest{
public static void main(String[] args) {
Superman superman=new Superman();
Human proxyInstance =(Human) ProxyFactory.getProxyInstance(superman);
String res= proxyInstance.getbelief();
System.out.println(res);
proxyInstance.eat("鸡公煲");
}
}