这杯咖啡有毒( ? ) -- Java 的反射机制
2018-01-04 10:22
489 查看
public class Creature<T> { public double weight; public void breath(){ System.out.println("呼吸!"); } }
@MyAnnotation(value = "oktfolio") public class Person extends Creature<String> implements Comparable, MyInterface { public String name; private int age; public Person() { } private Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @MyAnnotation(value = "adc") public void show() { System.out.println("I'm a human."); } private Integer display(String nation, Integer i) throws Exception { System.out.println("I'm from " + nation); return i; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Object o) { return 0; } class Bird { } public static void info() { System.out.println("Chinese"); } }
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.LOCAL_VARIABLE; @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.RUNTIME) public @interface MyAnnotation { String value(); }
import java.io.Serializable; public interface MyInterface extends Serializable { }
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Human { void info(); void fly(); } public class TestAOP { public static void main(String[] args) { SuperMan superMan = new SuperMan();//创建一个被代理类对象 Object object = MyProxy.getProxyInstance(superMan);//返回一个代理类的对象 Human human = (Human)object; human.info();//通过代理类的对象调用重写的抽象方法 human.fly(); } } //被代理类 class SuperMan implements Human { @Override public void info() { System.out.println("I'm superman"); } @Override public void fly() { System.out.println("I can fly!"); } } class MyInvocationHandler1 implements InvocationHandler { Object object; public void setObject(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { HumanUtil humanUtil = new HumanUtil(); humanUtil.method1(); Object returnVal = method.invoke(object, args); humanUtil.method2(); return returnVal; } } class HumanUtil { public void method1() { System.out.println("===方法一==="); } public void method2() { System.out.println("===方法二==="); } } //动态创建一个代理类的对象 class MyProxy { public static Object getProxyInstance(Object object) { MyInvocationHandler1 handler1 = new MyInvocationHandler1(); handler1.setObject(object); return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), handler1); } }
//静态代理模式 //接口 interface ClothFactory { void productCloth(); } //被代理类 class NikeClothFactory implements ClothFactory { @Override public void productCloth() { System.out.println("被代理类开始执行..."); } } //代理类 class ProxyFactory implements ClothFactory { ClothFactory cf; //创建代理类的对象时,实际传入被代理类的对象 public ProxyFactory(ClothFactory cf) { this.cf = cf; } @Override public void productCloth() { System.out.println("代理类开始执行..."); cf.productCloth(); } } public class TestClothProduct { public static void main(String[] args) { NikeClothFactory nikeClothFactory = new NikeClothFactory();//创建被代理类的对象 ProxyFactory proxyFactory = new ProxyFactory(nikeClothFactory);//创建代理类的对象 proxyFactory.productCloth(); } }
import org.junit.Test; import java.lang.reflect.Constructor; public class TestConstructor { @Test public void test1() throws ClassNotFoundException, IllegalAccessException, InstantiationException { String className = "Person"; Class clazz = Class.forName(className); //创建运行时类的对象。使用 newInstance(),实际上就是调用了运行时类的空参的构造器。 //要想能够创建成功:①要求对应的运行时类需要有空参的构造器 ②构造器的权限修饰符的权限要足够。 Person p = (Person) clazz.newInstance(); System.out.println(p); } @Test public void test2() throws ClassNotFoundException { String className = "Person"; Class clazz = Class.forName(className); Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor); } } }
import org.junit.Test; import java.lang.reflect.Field; import java.lang.reflect.Modifier; public class TestField { //获取对应的运行时类的属性 @Test public void test1() { Class clazz = Person.class; //getFields():只能获取到运行时类及其父类中声明为 public 的属性 Field[] fields = clazz.getFields(); for (Field field : fields) { System.out.println(field); } //getDeclaredFields();获取运行时类本身声明的所有的属性。 Field[] fields1 = clazz.getDeclaredFields(); for (Field field : fields1) { System.out.println(field); } } //权限修饰符 Modifiers 变量类型 Type 变量名 Name @Test public void test2() { Class clazz = Person.class; Field[] fields = clazz.getFields(); for (Field field : fields) { //1.获取每个属性的权限修饰符 System.out.print(Modifier.toString(field.getModifiers()) + " "); //2.获取属性的变量类型 System.out.print(field.getType() + " "); //3.获取属性名 System.out.println(field.getName()); } } //调用运行时类中指定的属性 @Test public void test3() throws NoSuchFieldException, IllegalAccessException, InstantiationException { Class clazz = Person.class; //1.获取指定的属性 //getField(String fieldName):获取运行时类中声明为 public 的指定属性名为 fieldName 的属性 Field name = clazz.getField("name"); //2.创建运行时类的对象 Person p = (Person) clazz.newInstance(); System.out.println(p); //3.将运行时类的指定的属性进行赋值 name.set(p, "Jerry"); System.out.println(p); System.out.println(); //getDeclaredField(String fieldName):获取运行时类中的指定属性名为 fieldName 的属性 Field age = clazz.getDeclaredField("age"); age.setAccessible(true);//私有方法需要setAccessible(true)才能操作私有属性 age.set(p, 10); System.out.println(p); } }
import com.sun.xml.internal.ws.api.model.ExceptionType; import org.junit.Test; import javax.sound.midi.Soundbank; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class TestMethod { //1.获取运行时类的方法 @Test public void test1() { Class clazz = Person.class; //getMethods():只能获取到运行时类及其父类中声明为 public 的方法 Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method); } //getDeclaredMethods():获取运行时类本身声明的所有的方法 Method[] methods1 = clazz.getDeclaredMethods(); for (Method method : methods1) { System.out.println(method); } } //注解 Annotation 权限修饰符 Modifiers 返回值类型 ReturnType 参数列表 异常 @Test public void test2() { Class clazz = Person.class; Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { //1.注解 Annotation[] annotations = method.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } //2.权限修饰符 System.out.print(Modifier.toString(method.getModifiers()) + " "); //3.返回值类型 System.out.print(method.getReturnType() + " "); //4.方法名 System.out.print(method.getName()); //5.参数列表 System.out.print("("); Class[] classes = method.getParameterTypes(); for (int i = 0; i < classes.length; i++) { System.out.print(classes[i].getName() + " args-" + i + ""); } System.out.print(")"); //6.异常 Class<?>[] exceptionTypes = method.getExceptionTypes(); if (exceptionTypes.length != 0) { System.out.print("throws "); } for (int i = 0; i < exceptionTypes.length; i++) { System.out.print(exceptionTypes[i].getName()); } System.out.println(); } } //调用运行时类中指定的方法 @Test public void test3() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException { Class clazz = Person.class; //getMethod(String methodName,Class..params):获取运行时类中声明为 public 的方法。 Method method = clazz.getMethod("show"); Person p = (Person) clazz.newInstance(); //调用指定的方法:invoke(Object obj,Object ...obj) Object returnVal = method.invoke(p); Method method1 = clazz.getMethod("toString 1050c "); Object returnVal1 = method1.invoke(p); System.out.println(returnVal1); //对于运行时类中的 static 方法调用 Method method2 = clazz.getMethod("info"); method2.invoke(Person.class); //getDeclaredMethod(String methodName,Class ...params):获取运行时类中的 Method method3 = clazz.getDeclaredMethod("display", String.class, Integer.class); method3.setAccessible(true); Object returnVal2 = method3.invoke(p, "China", 10); System.out.println(returnVal2); } //调用指定的构造器 @Test public void test4() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { String className = "Person"; Class clazz = Class.forName(className); Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class); constructor.setAccessible(true); Person p = (Person) constructor.newInstance("Tom",16); System.out.println(p); } }
import org.junit.Test; import java.lang.annotation.Annotation; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class TestOthers { //1.获取运行时类的父类 @Test public void test1() { Class clazz = Person.class; Class superClass = clazz.getSuperclass(); System.out.println(superClass); } //2.获取带泛型的父类 @Test public void test2() { Class clazz = Person.class; Type type = clazz.getGenericSuperclass(); System.out.println(type); } //3.获取父类的泛型 @Test public void test3() { Class clazz = Person.class; Type type = clazz.getGenericSuperclass(); ParameterizedType parameterizedType = (ParameterizedType) type; Type[] types = parameterizedType.getActualTypeArguments(); for (Type type1 : types) { System.out.println(((Class)type1).getName()); } } //4.获取实现的接口 @Test public void test4(){ Class clazz = Person.class; Class[] interfaces = clazz.getInterfaces(); for (Class anInterface : interfaces) { System.out.println(anInterface); } } //5.获取所在的包 @Test public void test5(){ Class clazz = Person.class; Package aPackage = clazz.getPackage(); System.out.println(aPackage); } //6.获取注解 @Test public void test6(){ Class clazz = Person.class; Annotation[] annotations = clazz.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } } }
//动态代理的使用 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; interface Subject { void action(); } //被代理类 class RealSubject implements Subject { @Override public void action() { System.out.println("被代理类执行"); } } class MyInvocationHandler implements InvocationHandler { Object object;//实现了接口的被代理类的对象的声明 //①给被代理的对象实例化 ②返回一个代理类的对象 public Object bind(Object object) { this.object = object; return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), this); } //当通过代理类的对象发起对被重写的方法的调用时,都会转换为对如下的 invoke 方法的调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //method 方法的返回值是 returnVal Object returnVal = method.invoke(object, args); return returnVal; } } public class TestProxy { public static void main(String[] args) { //1.被代理类的对象 RealSubject realSubject = new RealSubject(); //2.创建一个实现了 InvocationHandler 接口的对象 MyInvocationHandler handler = new MyInvocationHandler(); //3.调用 bind() 方法,动态的返回一个同样实现了 real 所在类实现的接口 Subject 的代理类的对象 Object object = handler.bind(realSubject); Subject subject = (Subject) object;//此时的 subject 就是代理类的对象 /*Object returnVal = */ subject.action();//转到 InvocationHandler 接口的实现类的 invoke() 方法调用 /* System.out.println(returnVal);*/ //再举一个例子 NikeClothFactory nikeClothFactory = new NikeClothFactory(); MyInvocationHandler handler1 = new MyInvocationHandler(); ClothFactory clothFactory = (ClothFactory) handler1.bind(nikeClothFactory); clothFactory.productCloth(); } }
import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Properties; public class TestReflection { //关于类的加载器 ClassLoader @Test public void Test5() throws ClassNotFoundException, IOException { ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println(classLoader); ClassLoader classLoader1 = classLoader.getParent(); System.out.println(classLoader1); ClassLoader classLoader2 = classLoader1.getParent(); System.out.println(classLoader2); Class clazz = Person.class; ClassLoader classLoader3 = clazz.getClassLoader(); System.out.println(classLoader3); String className = "java.lang.Object"; Class clazz1 = Class.forName(className); ClassLoader classLoader4 = clazz1.getClassLoader(); System.out.println(classLoader4); //掌握 //法一: ClassLoader classLoader5 = this.getClass().getClassLoader(); InputStream is = classLoader5.getResourceAsStream("jdbc.properties"); //法二: FileInputStream fis = new FileInputStream(new File("jdbc.properties")); Properties properties = new Properties(); properties.load(is); String username = properties.getProperty("username"); System.out.println(username); String password = properties.getProperty("password"); System.out.println(password); } //如何获取 Class 的实例 @Test public void test4() throws ClassNotFoundException { //1.调用运行时类本身的 .class 属性。 Class<Person> clazz = Person.class; System.out.println(clazz.getName()); Class clazz1 = String.class; System.out.println(clazz1.getName()); //2.通过运行时类的对象获取 Person p = new Person(); Class clazz2 = p.getClass(); System.out.println(clazz2.getName()); //3.通过 Class 的静态方法获取。体现反射的动态性。 String className = "Person"; Class clazz3 = Class.forName(className); System.out.println(clazz3.getName()); //4.通过类的加载器ClassLoader ClassLoader classLoader = this.getClass().getClassLoader(); Class clazz4 = classLoader.loadClass(className); System.out.println(clazz4.getName()); } /* * java.lang.Class: 是放射的源头。 * * 我们创建了一个类,通过编译 ( javac.exe ) ,生成对应的 .class 文件。 * 之后我们用 java.exe 加载 ( JVM 的类加载器 ) 此 .class文件。 * 此 .class 文件加载到内存以后,就是一个运行时类,存在缓存区。 * 那么这个运行时类本身就是一个 Class 的示例。 * * 1.每一个运行时类只加载一次! * 2.有了 Class 的实例以后,我们才可以进行如下的操作。 * 1)*创建对应的运行时类的对象 * 2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解、...) * 3)*调用对应的运行时类指定的结构(属性、方法、构造器) * 4)反射的应用:动态代理 * */ @Test public void test3() { Person p = new Person(); Class clazz = p.getClass();//通过运行时类的对象,调用其 getClass() 方法返回其运行时类 System.out.println(clazz); } //有了反射,可以通过反射创建一个类的对象, 并调用其中的结构 @Test public void test2() throws IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException { Class<Person> clazz = Person.class; //1.创建 clazz 对应的运行时类 Person 类的对象。 Person p = clazz.newInstance(); System.out.println(p); //2.通过反射调用运行时类指定的属性 //2.1 public Field f1 = clazz.getField("name"); f1.set(p, "Tony"); System.out.println(p); //2.2 private Field f2 = clazz.getDeclaredField("age"); f2.setAccessible(true); f2.set(p, 15); System.out.println(p); Method m1 = clazz.getMethod("show"); m1.invoke(p); Method m2 = clazz.getMethod("display", String.class); m2.invoke(p, "Zhongguo"); } // 在有反射以前,如何创建一个类的对象,并调用其中的方法、属性。 @Test public void test1() throws Exception { Person p = new Person(); p.setAge(18); p.setName("Jack"); p.show(); //p.display("China"); System.out.println(p); } }
相关文章推荐