您的位置:首页 > 编程语言 > Java开发

这杯咖啡有毒( ? ) -- 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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java