Java反射机制(三)
来源:互联网 发布:淘宝仓库宝贝多久删除 编辑:程序博客网 时间:2024/04/30 18:13
动态代理
实现动态代理机制,需要使用到java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类
InvocationHandler接口的定义如下
public interface invocationHandler
{
public Object invoke(Object Proxy,Method method,Object[] args) throws Throwable;
}
InvocationHandler接口中只有一个invoke()方法,此方法3个参数的含义为
Object Proxy:被代理的对象
Method Method:要调用的方法
Object[] args:调用的方法所需要的参数
Proxy类可以为一个或多个接口动态的生成实现类,Proxy类提供的操作方法如下:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
通过newProxyInstance方法可以动态的生成实现类,此方法中3个参数的含义为:
ClassLoader loader:类加载器
Class<?> interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的实例
PS:
ClassLoader是类加载器,java中主要有3中类加载器:
Bootstrap ClassLoader:此加载器使用C++编写,一般在开发中看不到的
Extension ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
AppClassLoader:加载Classpath指定的类,是最常用的一种加载器
范例1:
取得类加载器
package com.zgy.proxy;
public class Person
{
}
package com.zgy.proxy;
public class ClassLoaderTest
{
public static void main(String[] args)
{
Person per = new Person();
System.out.println("类加载器:"+per.getClass().getClassLoader().getClass().getName());
}
}
结果输出:
类加载器:sun.misc.Launcher$AppClassLoader
由此看以看出,默认的类加载器就是AppClassLoader
范例2:
定义一个InvocationHandler接口的实现类
package com.zgy.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 定义MuInvacationHandler类实现InvacationHandler接口
*/
public class MyInvocationHandler implements InvocationHandler
{
private Object obj; //真实的主题
public Object bind(Object obj) //绑定真实的主题
{
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
this); //取得代理对象
}
public Object invoke(Object proxy,Method method,Object[]args) throws Throwable
{ //动态调用方法
Object temp = method.invoke(this.obj,args);//调用方法,传入真实的主题和参数
return temp;//返回方法的信息
}
}
定义接口
package com.zgy.proxy;
public interface Subject //定义Subject接口
{
public String say(String name,int age); //定义抽象方法
}
定义真实主题实现类
package com.zgy.proxy;
public class RealSubject implements Subject
{
public String say(String name,int age) //实现接口中的抽象方法
{
return "姓名"+name+" "
+ "年龄"+age;
}
}
定义动态代理测试类
package com.zgy.proxy;
public class DynamicProxyTest
{
public static void main(String[] args)
{
MyInvocationHandler mh = new MyInvocationHandler();//实例化代理操作类
Subject sub = (Subject)mh.bind(new RealSubject());//绑定对象
String info = sub.say("张三", 24); //通过动态代理调用方法
System.out.println(info);
}
}
利用反射实现工厂设计模式
范例:
1.创建接口Fruit
package com.zgy.factory;
public interface Fruit
{
public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;
public class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
3.创建接口的实现类Orange
package com.zgy.factory;
public class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
4.创建工厂类
package com.zgy.factory;
public class Factory
{
public static Fruit getInstance(String className)
{
Fruit fruit = null;
try
{
fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
}
catch(Exception e)
{
e.printStackTrace();
}
return fruit;
}
}
5.实现测试类
package com.zgy.factory;
public class FactoryTest
{
public static void main(String[] args)
{
Fruit apple = Factory.getInstance("com.zgy.factory.Apple");
apple.eat();
}
}
以上操作可以看出,无论新增多少子类,工厂类Factory都不必做修改。
结合属性文件的工厂模式
以上的操作中要写入类完整的包.类名称,但是用户无法知道一个接口到底有多少实现类,此时可以通过属性文件的形式配置所需要的子类信息
范例:
1.创建接口Fruit
package com.zgy.factory;
public interface Fruit
{
public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;
public class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
3.创建接口的实现类Orange
package com.zgy.factory;
public class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
4.创建工厂类
package com.zgy.factory;
public class Factory
{
public static Fruit getInstance(String className)
{
Fruit fruit = null;
try
{
fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
}
catch(Exception e)
{
e.printStackTrace();
}
return fruit;
}
}
5.创建操作属性类
package com.zgy.factory;
/*
* 此类主要是取得属性文件中的内容,如果属性文件存在这读取,如果属性文件不存在则创建
*/
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class Init
{
public static Properties getPro()
{
Properties pro = new Properties();
File f = new File("D:"+File.separator+"fruit.properties");
try
{
if(f.exists())//属性文件存在
{
pro.load(new FileInputStream(f));//读取属性
}
else //属性文件不存在,创建并设置默认值
{
pro.setProperty("apple", "com.zgy.factory.Apple");
pro.setProperty("orange", "com.zgy.factory.Orange");
}
}
catch(Exception e)
{
e.printStackTrace();
}
return pro;
}
}
6.创建测试类
package com.zgy.factory;
import java.util.Properties;
public class FactoryTest02
{
public static void main(String[] args)
{
Properties pro = Init.getPro();
Fruit orange = Factory.getInstance(pro.getProperty("orange"));
if(orange != null)
{
orange.eat();
}
}
实现动态代理机制,需要使用到java.lang.reflect.InvocationHandler接口和java.lang.reflect.Proxy类
InvocationHandler接口的定义如下
public interface invocationHandler
{
public Object invoke(Object Proxy,Method method,Object[] args) throws Throwable;
}
InvocationHandler接口中只有一个invoke()方法,此方法3个参数的含义为
Object Proxy:被代理的对象
Method Method:要调用的方法
Object[] args:调用的方法所需要的参数
Proxy类可以为一个或多个接口动态的生成实现类,Proxy类提供的操作方法如下:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
通过newProxyInstance方法可以动态的生成实现类,此方法中3个参数的含义为:
ClassLoader loader:类加载器
Class<?> interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的实例
PS:
ClassLoader是类加载器,java中主要有3中类加载器:
Bootstrap ClassLoader:此加载器使用C++编写,一般在开发中看不到的
Extension ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类
AppClassLoader:加载Classpath指定的类,是最常用的一种加载器
范例1:
取得类加载器
package com.zgy.proxy;
public class Person
{
}
package com.zgy.proxy;
public class ClassLoaderTest
{
public static void main(String[] args)
{
Person per = new Person();
System.out.println("类加载器:"+per.getClass().getClassLoader().getClass().getName());
}
}
结果输出:
类加载器:sun.misc.Launcher$AppClassLoader
由此看以看出,默认的类加载器就是AppClassLoader
范例2:
定义一个InvocationHandler接口的实现类
package com.zgy.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/*
* 定义MuInvacationHandler类实现InvacationHandler接口
*/
public class MyInvocationHandler implements InvocationHandler
{
private Object obj; //真实的主题
public Object bind(Object obj) //绑定真实的主题
{
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
this); //取得代理对象
}
public Object invoke(Object proxy,Method method,Object[]args) throws Throwable
{ //动态调用方法
Object temp = method.invoke(this.obj,args);//调用方法,传入真实的主题和参数
return temp;//返回方法的信息
}
}
定义接口
package com.zgy.proxy;
public interface Subject //定义Subject接口
{
public String say(String name,int age); //定义抽象方法
}
定义真实主题实现类
package com.zgy.proxy;
public class RealSubject implements Subject
{
public String say(String name,int age) //实现接口中的抽象方法
{
return "姓名"+name+" "
+ "年龄"+age;
}
}
定义动态代理测试类
package com.zgy.proxy;
public class DynamicProxyTest
{
public static void main(String[] args)
{
MyInvocationHandler mh = new MyInvocationHandler();//实例化代理操作类
Subject sub = (Subject)mh.bind(new RealSubject());//绑定对象
String info = sub.say("张三", 24); //通过动态代理调用方法
System.out.println(info);
}
}
利用反射实现工厂设计模式
范例:
1.创建接口Fruit
package com.zgy.factory;
public interface Fruit
{
public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;
public class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
3.创建接口的实现类Orange
package com.zgy.factory;
public class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
4.创建工厂类
package com.zgy.factory;
public class Factory
{
public static Fruit getInstance(String className)
{
Fruit fruit = null;
try
{
fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
}
catch(Exception e)
{
e.printStackTrace();
}
return fruit;
}
}
5.实现测试类
package com.zgy.factory;
public class FactoryTest
{
public static void main(String[] args)
{
Fruit apple = Factory.getInstance("com.zgy.factory.Apple");
apple.eat();
}
}
以上操作可以看出,无论新增多少子类,工厂类Factory都不必做修改。
结合属性文件的工厂模式
以上的操作中要写入类完整的包.类名称,但是用户无法知道一个接口到底有多少实现类,此时可以通过属性文件的形式配置所需要的子类信息
范例:
1.创建接口Fruit
package com.zgy.factory;
public interface Fruit
{
public void eat();
}
2.创建接口的实现类Apple
package com.zgy.factory;
public class Apple implements Fruit
{
public void eat()
{
System.out.println("吃苹果");
}
}
3.创建接口的实现类Orange
package com.zgy.factory;
public class Orange implements Fruit
{
public void eat()
{
System.out.println("吃橘子");
}
}
4.创建工厂类
package com.zgy.factory;
public class Factory
{
public static Fruit getInstance(String className)
{
Fruit fruit = null;
try
{
fruit = (Fruit)Class.forName(className).newInstance();//根据传入的类名实例化Fruit接口
}
catch(Exception e)
{
e.printStackTrace();
}
return fruit;
}
}
5.创建操作属性类
package com.zgy.factory;
/*
* 此类主要是取得属性文件中的内容,如果属性文件存在这读取,如果属性文件不存在则创建
*/
import java.io.File;
import java.io.FileInputStream;
import java.util.Properties;
public class Init
{
public static Properties getPro()
{
Properties pro = new Properties();
File f = new File("D:"+File.separator+"fruit.properties");
try
{
if(f.exists())//属性文件存在
{
pro.load(new FileInputStream(f));//读取属性
}
else //属性文件不存在,创建并设置默认值
{
pro.setProperty("apple", "com.zgy.factory.Apple");
pro.setProperty("orange", "com.zgy.factory.Orange");
}
}
catch(Exception e)
{
e.printStackTrace();
}
return pro;
}
}
6.创建测试类
package com.zgy.factory;
import java.util.Properties;
public class FactoryTest02
{
public static void main(String[] args)
{
Properties pro = Init.getPro();
Fruit orange = Factory.getInstance(pro.getProperty("orange"));
if(orange != null)
{
orange.eat();
}
}
}
0 0
- Java反射机制(三)
- java反射机制(三)
- Java反射机制三
- 候捷谈Java反射机制(三)
- 候捷谈Java反射机制(三)
- 浅聊Java反射机制(三)
- JAVA基础 (三)反射 深入解析反射机制
- Java中的反射机制(三) 利用反射访问私有
- Java反射机制总结三
- JAVA反射机制学习(三)
- Java反射机制剖析(三)-简单谈谈动态代理
- java反射机制与动态代理(三)
- java反射机制(获取class的三种方式)
- 深入浅出学习hibernate框架(三):java的反射机制
- Java反射机制剖析(三)-简单谈谈动态代理
- Java反射机制剖析(三)-简单谈谈动态代理
- Java反射机制剖析(三)-简单谈谈动态代理
- java反射机制剖析(三)—类类型Class
- uva 1378 - A Funny Stone Game sg博弈
- 【HDU】2014上海全国邀请赛——题目重现(感谢上海大学提供题目) 题解
- 理解webservice
- 程序中JSP EL表达式没有执行的可能原因
- Android平台URI简介及使用
- Java反射机制(三)
- Object C中nil Nil NULL NSNull的区别
- 久赌必赢的秘诀,赌大小必赢技巧
- 久赌必赢的秘诀,赌大小必赢技巧
- 久赌必赢的秘诀,赌大小必赢技巧
- 职场新人应该如何为人处世:踏实做事,诚实做人
- 链队列的初始化,入队,出队,计算队的长度,遍历链队销毁队列
- 真人色碟技巧,网上色碟游戏技巧
- Activity间传类对象数据