-
获取class的方式
package reflection;
//关于反射
import java.lang.reflect.*;
import java.lang.reflect.Constructor;
import java.util.*;
public class Test {
//reflect包下核心接口和类
/**
* Member 接口 - 反映关于单个成员(字段或方法)或构造函数的标识信息。
* Field 类 - 提供一个类的域的信息以及访问类的域的接口。
* Method 类 - 提供一个类的方法的信息以及访问类的方法的接口。
* Constructor 类 - 提供一个类的构造函数的信息以及访问类的构造函数的接口。
* Array 类 - 该类提供动态地生成和访问 JAVA 数组的方法。
* Modifier 类 - 提供了 static 方法和常量,对类和成员访问修饰符进行解码。
* Proxy 类 - 提供动态地生成代理类和类实例的静态方法。
*/
//获取class的三种方式
//1.Class.forName(),使用类的全限定名
public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// try {
// Class c1= Class.forName("[D");
// System.out.println(c1.getName()); //虚拟机中的class的表示
// System.out.println(c1.getCanonicalName());//更具体的表示,对于array和内部类来说
// Class c2 =Class.forName("[Ljava.lang.String;");
// System.out.println(c2.getCanonicalName());
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
testClass();
System.out.println("");
testGetClass();
System.out.println("");
testInstanceOf();
System.out.println("");
testNewInstance();
}
//.class()
public static void testClass(){
Class c1 =int.class;
System.out.println(c1.getCanonicalName());
Class c2=Test.class;
System.out.println(c2.getCanonicalName());
}
//使用Object.getClass
public static void testGetClass(){
Class c1="zhouy".getClass();
System.out.println(c1.getCanonicalName());
Set<String> set =new HashSet<>();
Class c2 =set.getClass();
System.out.println(c2.getCanonicalName());
}
//判断某个对象是否位某个类的实例
public static void testInstanceOf(){
ArrayList arrayList =new ArrayList();
System.out.println(arrayList instanceof List);
}
//创建实例
/**
* 1.用Class对象的newInstance
* 2.用Constructor对象的newInstance
*/
public static void testNewInstance() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//1.
Class<StringBuffer> c1 = StringBuffer.class;
StringBuffer stringBuffer = c1.newInstance();
System.out.println(stringBuffer.append("aaa"));
//2.
Class<String> c2 = String.class;
Constructor<String> constructor = c2.getConstructor(c2);
String s = constructor.newInstance("bbb");
System.out.println(s);
}
}
//output:
int
reflection.Test
java.lang.String
java.util.HashSet
true
aaa
bbb
-
获取Field
package reflection;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Test2{
public boolean[][] b = {{false, false}, {true, true}};
public String name="zhouy";
public List<Integer> list= new ArrayList<>(Arrays.asList(1,2,3));
private String lover="???";
}
/**
* getFiled - 根据名称获取公有的(public)类成员。
* getDeclaredField - 根据名称获取已声明的类成员。但不能得到其父类的类成员。
* getFields - 获取所有公有的(public)类成员。
* getDeclaredFields - 获取所有已声明的类成员。
*/
public class FieldDemo {
public static void main(String[] args) throws NoSuchFieldException {
// Field b = Test2.class.getField("b");
// System.out.println(b);
// System.out.println(b.getType());
//
// Field name = Test2.class.getField("name");
// System.out.println(name.getType());
// Field[] fields = Test2.class.getFields();
// for (Field field : fields) {
// System.out.println(field.getType());
// }
//无法获取private,只能获取public
// System.out.println(Test2.class.getField("lover").getType());
//可以获取全部
System.out.println(Test2.class.getDeclaredField("lover").getType());
}
}
//output:
class java.lang.String
-
获取method和上面基本一样
package reflection;
/**
* getMethod - 返回类或接口的特定方法。其中第一个参数为方法名称,后面的参数为方法参数对应 Class 的对象。
* getDeclaredMethod - 返回类或接口的特定声明方法。其中第一个参数为方法名称,后面的参数为方法参数对应 Class 的对象。
* getMethods - 返回类或接口的所有 public 方法,包括其父类的 public 方法。
* getDeclaredMethods - 返回类或接口声明的所有方法,包括 public、protected、默认(包)访问和 private 方法,但不包括继承的方法。
*/
public class MethodDemo {
}
-
获取构造函数
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/**
* getConstructor - 返回类的特定 public 构造方法。参数为方法参数对应 Class 的对象。
* getDeclaredConstructor - 返回类的特定构造方法。参数为方法参数对应 Class 的对象。
* getConstructors - 返回类的所有 public 构造方法。
* getDeclaredConstructors - 返回类的所有构造方法。
*
*/
public class ConstructorDemo{
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//获取所有构造方法
// Constructor<?>[] declaredConstructors = String.class.getDeclaredConstructors();
// for (Constructor declaredConstructor : declaredConstructors) {
// System.out.println(declaredConstructor);
// }
Constructor<String> constructor = String.class.getConstructor(String.class);
System.out.println(constructor);
String s = constructor.newInstance("I love java");
System.out.println(s);
}
}
//output:
public java.lang.String(java.lang.String)
I love java
-
静态代理
package reflection;
/**
* 静态代理模式(时间模式中)
*/
interface Marry{
void doMarry();
}
class You implements Marry{
@Override
public void doMarry() {
System.out.println("我要结婚了");
}
}
class WeddingCompany implements Marry{ //作为代理中介
private You you;
public WeddingCompany(You you){
this.you =you;
}
@Override
public void doMarry() {
if(you!=null){
System.out.println("你要化妆");
System.out.println("你要去接亲");
you.doMarry();
System.out.println("你结账");
}
}
}
//如上就是静态代理
public class ProxyTest {
public static void main(String[] args) {
You you =new You();
Marry yourMarry =new WeddingCompany(you);
yourMarry.doMarry();
}
}
-
动态代理
package reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 1.在运行状态中,需要时Subject和RealSubject中动态的创建一个Proxy,用完即销毁
* 使用InvocationHandler接口负责所有Proxy类方法的调用,Proxy类需实现该接口
*/
interface Subject{
void hello(String str);
String bye();
}
class RealSubject implements Subject{
@Override
public void hello(String str) {
System.out.println("Hello"+str);
}
@Override
public String bye() {
System.out.println("Goodbye");
return "over";
}
}
//创建动态代理类
class ProxyDemo implements InvocationHandler{
//要代理的对象
private Subject subject;
public ProxyDemo(Subject subject){
this.subject=subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("Before method");
System.out.println("Call method:" + method);
// 当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler(InvocatioinHandler的实例)对象的invoke方法来进行调用
Object invoke = method.invoke(subject, args);
System.out.println("After method");
return invoke;
}
}
public class DynamicProxyTest {
public static void main(String[] args) {
Subject subject =new RealSubject(); //要代理的真实对象subject
// 我们要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法的
InvocationHandler handler =new ProxyDemo(subject);//初始化处理器
/*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
*/
Subject proxySubject =(Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler);
System.out.println(proxySubject.getClass().getCanonicalName());
proxySubject.hello("zhouy");
String bye = proxySubject.bye();
System.out.println("last:"+bye);
}
}
//output
reflection.$Proxy0
Before method
Call method:public abstract void reflection.Subject.hello(java.lang.String)
Hellozhouy
After method
Before method
Call method:public abstract java.lang.String reflection.Subject.bye()
Goodbye
After method
last:over