热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java反射机制及动态代理

目前正在看HadoopRPC框架的源码,在深入了解这些之前,有一些基础知识需要回顾下。1.java反射机制及动态代理2.java网络编程3.javaNIO先总结下第一个,java反射机制及动态代理的相关知识点:java反射机制在看与java反射机制相关的代码前,试着看看

目前正在看Hadoop RPC框架的源码,在深入了解这些之前,有一些基础知识需要回顾下。 1. java反射机制及动态代理 2. java网络编程 3. java NIO 先总结下第一个,java反射机制及动态代理的相关知识点: java反射机制 在看与java反射机制相关的代码前,试着看看

目前正在看Hadoop RPC框架的源码,在深入了解这些之前,有一些基础知识需要回顾下。

  • 1. java反射机制及动态代理
  • 2. java网络编程
  • 3. java NIO

先总结下第一个,java反射机制及动态代理的相关知识点:

java反射机制

在看与java反射机制相关的代码前,试着看看下面这几个问题:

  1. 什么是反射?
  2. 为什么使用反射?
  3. 使用它有哪些好处?
  4. 哪些地方需要反射?

在程序运行时,允许改变程序结构和变量名称。如python ,ruby这类,我们称为是动态语言。

而对于java,C++,C# 这类则不能称为动态语言,我们一般称这些为静态语言。

int i = 1
i = “hello world ”

如上面这段代码,在静态语言中,在编译阶段编译器就会报错。而对于动态语言,是可以修改变量类型的,如下面:

i = 1
i = ‘hi’

1. 先尝试看看第一个问题,什么是反射机制?

在运行时环境,动态获取类的信息以及动态调用对象的方法的功能,就是reflection机制。

2. 哪些地方需要反射?

* 运行时判断任何一个对象所属的类
* 运行时构造任何一个类的对象
* 运行时判断任何一个类所具有的成员变量和方法
* 运行时调用任何一个对象的方法

3. 反射的使用?

先看看java reflection api, Class类是反射的入口点。有下面3种方式获取:

1. Class.forName(“java.util.Data”)
2. T.getClass()
3. T.class

一个Class对象实际表示一个类型,但这个类型不一定是一种类。比如说int不表示类,但是int.class是一个Class类型的对象。

注:数组类型,使用getName会返回一个很奇怪的名字,如:

System.out.println(Double[].class.getName());
显示打印的值如下:
[Ljava.lang.Double;

创建一个类的实例newInstance方法:使用默认的构造函数,没有参数

T.class.newInstance();
Object objCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

反射分析类的能力:

  • 1. java.lang.reflect包下面有3个类,Field,Method,Constructor,分别用来描述属性,方法,构造函数
  • 2. 还有一个修饰符的获取,Modifier

4. 一个反射的简单例子程序:

package com.lifeware.study.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectTetser {
public Object copy(Object obj) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException{
Class classType = obj.getClass();
System.out.println(classType.getName());
Object objCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

Field[] fields = classType.getDeclaredFields();
for(Field field:fields){
System.out.println(field.getName());
String firstLetter = field.getName().substring(0,1).toUpperCase();
String getMethodName = “get” + firstLetter + field.getName().substring(1);
String setMethodName = “set” + firstLetter + field.getName().substring(1);

Method getMethod = classType.getMethod(getMethodName, new Class[]{});
Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});

Object value = getMethod.invoke(obj, new Object[]{});
setMethod.invoke(objCopy, new Object[]{value});
}
return objCopy;
}
/**
* @param args
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws SecurityException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
// TODO Auto-generated method stub
Customer cus = new Customer();
cus.setId(new Long(100));
cus.setAge(new Long(50));
cus.setName(“zhangsan”);
Customer cuscopy = (Customer) new ReflectTetser().copy(cus);
System.out.println(cuscopy.getId() + “,” + cuscopy.getAge() + “,” + cuscopy.getName());
}
}
class Customer{
private Long id;
private Long age;
private String name;

public Customer(){

}

public Long getId(){
return id;
}

public Long getAge(){
return age;
}

public String getName(){
return name;
}

public void setId(Long id){
this.id = id;
}

public void setAge(Long age){
this.age = age;
}

public void setName(String name){
this.name = name;
}
}

5. 当然,反射写通用的数组代码时,还需要用到:java.lang.reflect.Array

public static Object goodArrayGrow(Object a){
Class c1 = a.getClass();
if(!c1.isArray()){
return null;
}
Class compOnentType= c1.getComponentType();
int length = Array.getLength(a);
int newLength = length * 11/10 + 10;
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(a, 0, newArray, 0, length);

return newArray;
}

动态代理

动态代理部分:想清楚下面四个问题

1.什么是动态代理?
一种用于转发请求,进行特殊处理的机制,“动态”应该指的是“运行期”。
2.为什么使用动态代理?
可以对请求进行任何处理(如事务,日志等,这都是网上说的,我当然可以做任何处理)
3.使用它有哪些好处?
如上
4.哪些地方需要动态代理?
不允许直接访问某些类;对访问要做特殊处理等,我只能想到这些。

1. 和动态代理有关的有两个类

1.1 interface InvocationHandler

只这一个方法, Object invoke(Object proxy, Method method, Object[] args)

1.2 class Proxy 真正表示动态代理的类,提供两个静态方法:

Class getProxyClass(ClassLoader loader, Class[] interface)

用来产生代理类,参数要提供interface数组,它会生成这些interface的“虚拟实现”,

用来冒充真实的对象。

Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

产生代理对象,多了InvocationHandler参数(只是InvocationHandler接口的实现类),

它与代理对象关联,当请求分发到代理对象后,会自动执行h.invoke(…)方法.

2. 动态机制的实现步骤:

/**
* 1. 实现InvocationHandler接口创建自己的调用处理器
* InvocationHandler handler = new InvocationHandlerImpl(server);
* 2. 通过Proxy指定ClassLoader对象和一组interface创建动态代理类
* Class clazz = Proxy.getProxyClass(classLoader,new class[]{…})
* 3. 通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型:
* Constructor cOnstructor= clazz.getConstructor(new Class[]{InvocationHandler.class})
* 4. 通过构造函数创建动态代理类实例,将调用处理器对象作为参数被传入
* Interface proxy = constructor.newInstance(new Object[]{handler})
*
* Proxy中newProxyInstance方法已经封装了步骤2~4,实例如下:
*/

3. 一个简单实用的例子:

package com.lifeware.study.reflection;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxyTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
CalculatorProtocol server = new Server();
InvocationHandler handler = new CalculatorHandler(server);
CalculatorProtocol client = (CalculatorProtocol)Proxy.newProxyInstance(server.getClass().getClassLoader(),
server.getClass().getInterfaces(), handler);
int result = client.add(3, 2);
System.out.println(“3+2=” + result);
result = client.subtract(5, 2);
System.out.println(“5-2=” + result);
}
}
//定义一个接口协议
interface CalculatorProtocol{
public int add(int a,int b);
public int subtract(int a,int b);
}
//实现接口协议
class Server implements CalculatorProtocol{
public int add(int a,int b){
return a+b;
}

public int subtract(int a,int b){
return a-b;
}
}
class CalculatorHandler implements InvocationHandler{
private Object objOriginal;
public CalculatorHandler(Object obj){
this.objOriginal = obj;
}

public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
//可加入预处理
Object result = method.invoke(this.objOriginal, args);
return result;

}

}

~~EOF~~

推荐阅读
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • switch语句的一些用法及注意事项
    本文介绍了使用switch语句时的一些用法和注意事项,包括如何实现"fall through"、default语句的作用、在case语句中定义变量时可能出现的问题以及解决方法。同时也提到了C#严格控制switch分支不允许贯穿的规定。通过本文的介绍,读者可以更好地理解和使用switch语句。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • mapreduce源码分析总结
    这篇文章总结的非常到位,故而转之一MapReduce概述MapReduce是一个用于大规模数据处理的分布式计算模型,它最初是由Google工程师设计并实现的ÿ ... [详细]
  • 1、概述首先和大家一起回顾一下Java消息服务,在我之前的博客《Java消息队列-JMS概述》中,我为大家分析了:然后在另一篇博客《Java消息队列-ActiveMq实战》中 ... [详细]
  • 与.Net大师Jeffrey Richter面对面交流——TUP对话大师系列活动回顾(多图配详细文字)...
    与.Net大师JeffreyRichter面对面交流——TUP对话大师系列活动回顾(多图配文字)上周末很有幸参加了CSDN举行的TUP活动, ... [详细]
  • 只使用’if-else’语句的’else’部分是否可以接受?有时,我觉得检查所有条件是否都是真的更容易,但是只处理“其他”情况。我想 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文是一位90后程序员分享的职业发展经验,从年薪3w到30w的薪资增长过程。文章回顾了自己的青春时光,包括与朋友一起玩DOTA的回忆,并附上了一段纪念DOTA青春的视频链接。作者还提到了一些与程序员相关的名词和团队,如Pis、蛛丝马迹、B神、LGD、EHOME等。通过分享自己的经验,作者希望能够给其他程序员提供一些职业发展的思路和启示。 ... [详细]
  • Python字典推导式及循环列表生成字典方法
    本文介绍了Python中使用字典推导式和循环列表生成字典的方法,包括通过循环列表生成相应的字典,并给出了执行结果。详细讲解了代码实现过程。 ... [详细]
  • 项目需要将音视频文件上传服务器,考虑并发要求高,通过七牛来实现。直接上代码usingQiniu.IO;usingQiniu.IO.Resumable;usingQiniu.RPC; ... [详细]
  • java布尔字段用is前缀_POJO类中布尔类型的变量都不要加is前缀详解
    前言对应阿里巴巴开发手册第一章的命名风格的第八条。【强制】POJO类中布尔类型的变量都不要加is前缀,否则部分框架解析会引起序列化错误。反例:定义为基本 ... [详细]
  • 让你明白kvm是什么
    参考:https:blog.csdn.netbbwangjarticledetails80465320KVM工具集合:libvirt:操作和管理KVM虚机的虚拟化API ... [详细]
author-avatar
失败人一枚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有