反射学习笔记

反射被认为是动态语言的关键,给java提供了运行时动态获取一个类实例的可能。反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部构造方法,属性,方法,注解,异常等。反射在一些开源框架里使用的非常之多,比如:Spring,Struts,Hibnerate,MyBatics等。反射虽然很灵活,能够使得写的代码变的大幅精简,所以在用的时候一定要注意具体的应用场景。 
优点: 
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。 
(2)与Java动态编译相结合,可以实现无比强大的功能 
缺点: 
(1)使用反射的性能较低 
(2)使用反射相对来说不安全 
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性 


以下是个人的代码练习。

反射练习:

package com.bin.test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Test;

class Person {
	public String name;
	int age;

	public void sayHi() {
		System.out.println("Hi, 你好...");
	}

	public void show(String name, int age) {
		System.out.println("name:" + name + ", age:" + age);
	}

	private void display(String name, int age) {
		System.out.println("name:" + name + ", 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;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}


public class TestReflect {
	@Test
	public void test1() throws Exception {
		// Class clazz = Person.class;
		Class clazz = Class.forName("com.bin.test.Person");
		Person p = (Person) clazz.newInstance();
		System.out.println(p);

		//getField(String name)/getFields():只能获取到运行时类中及其父类中声明为public的属性
		Field name = clazz.getField("name");
		name.set(p, "tom");
		System.out.println(p);
		System.out.println(name.get(p));

		//getDeclaredField(String name)/getDeclaredFields():能够获取运行时类本身声明的所有属性
		Field age = clazz.getDeclaredField("age");
		age.setAccessible(true);
		age.set(p, 18);
		System.out.println(p);
		System.out.println(age.get(p));

		//getMethod(String name, Class... parameterTypes)/getMethods():
		//获取到运行时类及其父类中所有声明为public的方法
		Method sayHi = clazz.getMethod("sayHi");
		sayHi.invoke(p);

		Method show = clazz.getMethod("show", String.class, int.class);
		show.invoke(p, "Lily", 20);

		//getDeclaredMethod(String name, Class... parameterTypes)/getDeclaredMethods():
		//获取运行时类本身声明的所有方法
		Method display = clazz.getDeclaredMethod("display", String.class, int.class);
		display.setAccessible(true);
		display.invoke(p, "Jim", 30);
	}
}
  


简单的代理练习:
package com.bin.test;

interface ClothFactory {
	void product();
}

class NikeFactory implements ClothFactory {

	@Override
	public void product() {
		System.out.println("Product nike...");
	}

}

class NewBalanceFactory implements ClothFactory {

	@Override
	public void product() {
		System.out.println("Product NB...");
	}

}

class ClothFactoryProxy implements ClothFactory{
	ClothFactory cf;// 被代理对象

	public ClothFactoryProxy(ClothFactory cf) {
		super();
		this.cf = cf;
	}

	@Override
	public void product() {
		System.out.println("The proxy exec...");
		this.cf.product();
	}
	
}


public class TestProxy {
	public static void main(String[] args) {
		NikeFactory nike = new NikeFactory();
		ClothFactoryProxy nikeProxy = new ClothFactoryProxy(nike);
		nikeProxy.product();

		NewBalanceFactory nb = new NewBalanceFactory();
		ClothFactoryProxy nbProxy = new ClothFactoryProxy(nb);
		nbProxy.product();
	}
}
  


动态代理练习:
package com.bin.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


interface Animal {
	void sayHi(String name);
}

class Dog implements Animal {

	public void sayHi(String name) {
		System.out.println("I'am a " + name);
	}

}

class Cat implements Animal {

	@Override
	public void sayHi(String name) {
		System.out.println("I'am a " + name);
	}

}

class MyInvocationHandler implements InvocationHandler {
	Object obj;// 被代理对象

	public Object bind(Object obj) {
		this.obj = obj;
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object returnVal = method.invoke(obj, args);
		return returnVal;
	}

}


public class TestDynamicProxy {

	public static void main(String[] args) {
		Dog dog = new Dog();
		MyInvocationHandler handler = new MyInvocationHandler();
		Object a = handler.bind(dog);

		Animal a1 = (Animal) a;
		a1.sayHi("dog");

		Cat cat = new Cat();

		Animal a2 = (Animal) handler.bind(cat);
		a2.sayHi("cat");
	}
}
  


简单的AOP练习:
package com.bin.test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Human {
	public void info();

	public void fly();
}

class SuperMan implements Human {

	@Override
	public void info() {
		System.out.println("Hi,你好...");
	}

	@Override
	public void fly() {
		System.out.println("Hi,I can fly...");
	}

}

class HumanUtil {
	public void method1() {
		System.out.println("--- method 1 ---");
	}

	public void method2() {
		System.out.println("--- method 2 ---");
	}
}

class MyInvovationHandler implements InvocationHandler {

	Object obj;// 被代理对象

	public void setObj(Object obj) {
		this.obj = obj;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		HumanUtil hu = new HumanUtil();
		hu.method1();
		Object returnVal = method.invoke(obj, args);
		hu.method2();
		return returnVal;
	}

}

class MyProxy {
	public Object getProxyInstance(Object obj) {
		MyInvovationHandler handler = new MyInvovationHandler();
		handler.setObj(obj);

		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
	}
}

public class TestAOP {

	public static void main(String[] args) {
		SuperMan sm = new SuperMan();

		MyProxy p = new MyProxy();
		Object obj = p.getProxyInstance(sm);

		Human h = (Human) obj;
		h.info();
		System.out.println();
		h.fly();
	}

}
  


你可能感兴趣的:(Java,java,反射,代理)