`

浅谈Java反射机制(一)

 
阅读更多
Reflection,这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。 --来自百度百科定义

马上就要开始跟项目了,为了作些准备,了解了一下反射技术,今天想就自己对反射机制的了解作一些总结。

首先学习的是比较浅显的,通过传进来的对象去初始化一些变量,而这些变量是组成一个方法的必要条件,通过这些条件来调用指定的方法。界定一个唯一方法的因素有:
1,方法所属的类;
2,方法的名字;
3,方法的参数列表和顺序;
满足这三个条件,我们就可以通过java.lang.reflect.Method类,去创建一个Method类的对象method,通过method.invoke(affectedObject,params)来执行一个方法。

假定,我们现在是做远程的socket,通过流来传对象,对象皆为封装对象,即封装了需要用到的属性,类名、方法名、参数类型列表,参数列表:
[java] view plaincopyprint?package com.insigma.model; 
 
import java.io.Serializable; 
 
public class Call implements Serializable{ 
    private String className; 
    private String methodName; 
    private Class[] paramTypes; 
    private Object[] params; 
    private Object result; 
    public Call(){ 
         
    } 
    public Call(String className, String methodName,Class[] paramTypes, Object[] params){ 
        this.className = className; 
        this.methodName = methodName; 
        this.paramTypes = paramTypes; 
        this.params = params; 
    } 
     
    public String getClassName(){ 
        return className; 
    } 
    public String getMethodName(){ 
        return methodName; 
    } 
    public Class[] getParamTypes(){ 
        return paramTypes; 
    } 
    public Object[] getParams(){ 
        return params; 
    } 
    public Object getResult(){ 
        return result; 
    } 
    public void setResult(Object result){ 
        this.result = result; 
    } 


package com.insigma.model;

import java.io.Serializable;

public class Call implements Serializable{
private String className;
private String methodName;
private Class[] paramTypes;
private Object[] params;
private Object result;
public Call(){

}
public Call(String className, String methodName,Class[] paramTypes, Object[] params){
this.className = className;
this.methodName = methodName;
this.paramTypes = paramTypes;
this.params = params;
}

public String getClassName(){
return className;
}
public String getMethodName(){
return methodName;
}
public Class[] getParamTypes(){
return paramTypes;
}
public Object[] getParams(){
return params;
}
public Object getResult(){
return result;
}
public void setResult(Object result){
this.result = result;
}
}
因为要通过流来传输对象,最好把这对象实现可序列化接口Serializable。通过构造器来为封装的属性赋值。

接下来就是ServerSocket,在这里监听远程socket那边是否有对象传过来,以作反应:
[java] view plaincopyprint?package com.insigma.model; 
 
import java.io.*; 
import java.net.*; 
import java.util.*; 
import java.lang.reflect.*; 
 
public class SimpleServer { 
     
    private Map remoteObjects=new HashMap();    
    //存放远程对象的缓存  
    /** 把一个远程对象放到缓存中 */ 
    public void register(String className,Object remoteObject){ 
        remoteObjects.put( className,remoteObject);  
    } 
     
    public void service()throws Exception{ 
        ServerSocket serverSocket = new ServerSocket(8000); 
        System.out.println("服务器启动."); 
         
        while(true){ 
             
            Socket socket=serverSocket.accept(); 
            InputStream in=socket.getInputStream(); 
            ObjectInputStream ois=new ObjectInputStream(in); 
             
            OutputStream out=socket.getOutputStream(); 
            ObjectOutputStream oos=new ObjectOutputStream(out); 
             
            Call call=(Call)ois.readObject(); 
            //接收客户发送的Call对象  
            System.out.println(call); 
            call=invoke(call);       
             
            //调用相关对象的方法  
            oos.writeObject(call);    
             
            //向客户发送包含了执行结果的Call对象  
            ois.close();oos.close(); 
            socket.close(); 
             
        } 
         
    } 
    public Call invoke(Call call){ 
        Object result=null; 
        try{ 
             
            String className=call.getClassName(); 
            String methodName=call.getMethodName(); 
            Object[] params=call.getParams(); 
            Class classType=Class.forName(className); 
            Class[] paramTypes=call.getParamTypes(); 
            Method method=classType.getMethod(methodName, paramTypes);   
            Object remoteObject=remoteObjects.get(className); 
             
            //从缓存中取出相关的远程对象  
            if(remoteObject==null){ 
                throw new Exception(className+"的远程对象不存在"); 
            }else{ 
                result=method.invoke(remoteObject,params); 
                } 
        }catch(Exception e){ 
            result=e; 
        } 
         
        call.setResult(result);         
        //设置方法执行结果  
        return call; 
    } 
    public static void main(String args[])throws Exception { 
         
        SimpleServer server=new SimpleServer(); 
         
        //把事先创建的HelloServiceImpl对象加入到服务器的缓存中  
        server.register("com.insigma.model.HelloService",new HelloServiceImpl()); 
        server.service(); 
         
    }  
     


package com.insigma.model;

import java.io.*;
import java.net.*;
import java.util.*;
import java.lang.reflect.*;

public class SimpleServer {

private Map remoteObjects=new HashMap();  
//存放远程对象的缓存
/** 把一个远程对象放到缓存中 */
public void register(String className,Object remoteObject){
remoteObjects.put( className,remoteObject);
}

public void service()throws Exception{
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("服务器启动.");

while(true){

Socket socket=serverSocket.accept();
InputStream in=socket.getInputStream();
ObjectInputStream ois=new ObjectInputStream(in);

OutputStream out=socket.getOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(out);

Call call=(Call)ois.readObject();
//接收客户发送的Call对象
System.out.println(call);
call=invoke(call);     

//调用相关对象的方法
oos.writeObject(call);  

//向客户发送包含了执行结果的Call对象
ois.close();oos.close();
socket.close();

}

}
public Call invoke(Call call){
Object result=null;
try{

String className=call.getClassName();
String methodName=call.getMethodName();
Object[] params=call.getParams();
Class classType=Class.forName(className);
Class[] paramTypes=call.getParamTypes();
Method method=classType.getMethod(methodName, paramTypes); 
Object remoteObject=remoteObjects.get(className);

//从缓存中取出相关的远程对象
if(remoteObject==null){
throw new Exception(className+"的远程对象不存在");
}else{
result=method.invoke(remoteObject,params);
}
}catch(Exception e){
result=e;
}

call.setResult(result);       
//设置方法执行结果
return call;
}
public static void main(String args[])throws Exception {

SimpleServer server=new SimpleServer();

//把事先创建的HelloServiceImpl对象加入到服务器的缓存中
server.register("com.insigma.model.HelloService",new HelloServiceImpl());
server.service();

}

}
这里,需要注册类型,没有注册的类型,远程传过来的时候,会出现异常,这里大概是出于安全考虑。
下来就是Socket的客户端了
[java] view plaincopyprint?package com.insigma.model; 
 
import java.io.*; 
import java.net.*; 
 
public class SimpleClient { 
     
    public void invoke()throws Exception{ 
         
        Socket socket = new Socket("localhost",8000); 
        OutputStream out=socket.getOutputStream(); 
         
        ObjectOutputStream oos=new ObjectOutputStream(out); 
        InputStream in=socket.getInputStream(); 
        ObjectInputStream ois=new ObjectInputStream(in); 
        Call call=new Call("com.insigma.model.HelloService","getTime",new Class[]{},new Object[]{}); 
        //Call call=new Call("com.insigma.model.HelloService","echo",new Class[]{String.class},new Object[]{"Hello"});    
        oos.writeObject(call); 
        //向服务器发送Call对象  
        call=(Call)ois.readObject();        
        //接收包含了方法执行结果的Call对象  
        System.out.println(call.getResult()); 
        ois.close(); 
        oos.close(); 
        socket.close(); 
     
    } 
    public static void main(String args[])throws Exception { 
        new SimpleClient().invoke();  
         
    } 


package com.insigma.model;

import java.io.*;
import java.net.*;

public class SimpleClient {

public void invoke()throws Exception{

Socket socket = new Socket("localhost",8000);
OutputStream out=socket.getOutputStream();

ObjectOutputStream oos=new ObjectOutputStream(out);
InputStream in=socket.getInputStream();
ObjectInputStream ois=new ObjectInputStream(in);
Call call=new Call("com.insigma.model.HelloService","getTime",new Class[]{},new Object[]{});
//Call call=new Call("com.insigma.model.HelloService","echo",new Class[]{String.class},new Object[]{"Hello"}); 
oos.writeObject(call);
//向服务器发送Call对象
call=(Call)ois.readObject();      
//接收包含了方法执行结果的Call对象
System.out.println(call.getResult());
ois.close();
oos.close();
socket.close();

}
public static void main(String args[])throws Exception {
new SimpleClient().invoke();

}
}
当然咯,被反射的类也是必须贴上,不然给出一份不能运行的代码,肯定要被唾液淹死。对被反射的类,做了一个接口来解耦。
[java] view plaincopyprint?package com.insigma.model; 
 
 
public interface HelloService { 
    public String echo(String words); 
    public String getTime(); 


package com.insigma.model;


public interface HelloService {
public String echo(String words);
public String getTime();
}

这里是实现类,只提供很简单的测试功能。
[java] view plaincopyprint?package com.insigma.model; 
 
import java.util.Date; 
 
public class HelloServiceImpl implements HelloService{ 
 
    @Override 
    public String echo(String words) { 
         
        return "echo:" + words; 
    } 
 
    @Override 
    public String getTime() { 
         
        return new Date().toString(); 
    } 
     


package com.insigma.model;

import java.util.Date;

public class HelloServiceImpl implements HelloService{

@Override
public String echo(String words) {

return "echo:" + words;
}

@Override
public String getTime() {

return new Date().toString();
}

}
先运行服务端,再运行客户端,这小小的测试,也算完成了。


分享到:
评论

相关推荐

    Java反射技术浅谈.pdf

    Java反射技术浅谈 Java反射技术是一种强大的技术,它允许Java程序访问、检测和修改它自己的状态或行为。通过反射,Java程序可以加载一个运行时才知道名称的类,获取其完整的内部信息,并创建其对象,或者对其属性...

    Java反射技术浅谈 (1).pdf

    在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包。 * Class类:代表一个类。 * Field类:代表类的成员变量(成员变量也称为类的属性)。 * Method类:代表类的方法。 * Constructor类:...

    浅谈java反射和自定义注解的综合应用实例

    浅谈java反射和自定义注解的综合应用实例 Java 反射(Reflection)是 Java 语言中的一种机制,它允许程序在运行时检查和修改其结构和行为。Java 反射机制提供了一个实现运行时类型检查的机制,从而使得 Java 语言...

    浅谈MyBatis通用Mapper实现原理

    浅谈MyBatis通用Mapper实现原理 MyBatis通用Mapper是MyBatis框架中的一种通用Mapper实现方式,主要提供了一些通用的方法,这些方法是以接口的形式提供的。通用Mapper的实现原理主要是通过Java反射机制和MyBatis框架...

    浅谈用java实现事件驱动机制

    总之,Java虽然没有内置的事件驱动机制,但通过观察者模式和反射机制,我们可以构建出符合需求的事件驱动系统。观察者模式更适用于通用和灵活的场景,而反射则适合对已知对象结构的简单事件处理。在实际开发中,应...

    浅谈Java中对类的主动引用和被动引用

    浅谈Java中对类的主动引用和被动引用 Java 中的类引用可以分为两种:主动引用和被动引用。理解这两种引用机制对于 Java 程序的正确执行和优化至关重要。 一、主动引用 主动引用是指在 Java 程序中明确地使用某个...

    浅谈Java中的class类

    在Java编程语言中,`Class`类扮演着至关重要的角色,它是Java反射机制的基础。`Class`类代表了运行时的类信息,允许我们在程序运行时动态地获取类的结构和属性,包括类的成员变量、方法、构造器等。这使得Java具备了...

    浅谈java Properties类的使用基础

    Java Properties类的使用基础 Java Properties类是Java标准库中的一种配置类,继承自HashTable,通常...Java Properties类是Java标准库中的一种配置类,提供了便捷的配置信息读写和持久化机制,广泛应用于实际项目中。

    java基础PPT

    11. **JNI与JVM原理**:浅谈Java Native Interface(JNI),用于在Java程序中调用本地(非Java)代码,以及JVM的工作原理,包括类加载、内存管理和垃圾收集。 12. **案例分析**:可能包含一些简单的编程实例,帮助...

    浅谈Java编程中的内存泄露情况

    Java编程中的内存泄露是一个重要的议题,尤其是在大型应用和服务器端编程中,良好的内存管理能确保系统的稳定性和性能。本文将深入探讨Java中的内存泄露及其相关的JVM垃圾回收机制。 首先,与C++等语言不同,Java...

    浅谈使用java实现阿里云消息队列简单封装

    1. 消费者提供接口:使用Java的反射机制和动态代理生成对象,提供了一个接口,包括Topic、Tag、Body和Key等注解,消费者通过Tag进行消息的分类做不同的业务处理。 2. 生产者使用消费者提供的API发送消息:使用基于...

    浅谈计算机应用软件开发中编程语言的选择研究中英文对照.pdf

    浅谈计算机应用软件开发中编程语言的选择研究 随着信息技术的飞速发展,计算机应用软件已经深入到我们生活的各个领域,从个人娱乐、办公自动化到工业自动化、云计算等,无处不在。软件开发企业面临着激烈的市场竞争...

    java中Class.forName的作用浅谈

    1. **创建方式**:`newInstance()`是通过反射机制来创建对象,而`new`是直接创建。`newInstance()`要求类必须有一个无参构造器,而`new`可以调用任何公共构造器。 2. **灵活性与效率**:`newInstance()`提供了更大...

    java高手的文章合集1/3

    这个合集以“由一个简单的程序谈起”为主题,通过一系列文章深入浅出地介绍了Java语言的核心概念和技术。以下是这些文章可能涉及的重要知识点: 1. **Java入门**:文章可能从一个简单的“Hello, World!”程序开始,...

    浅谈对象与Map相互转化

    浅谈对象与Map相互转化 在 Java 开发中,对象与 Map 的相互转换是非常常见的需求。例如,在 Web 项目中,我们需要将 Java 对象转换为 JSON 数据,以便于前端 JavaScript 代码对其进行处理。又或者,在数据处理时,...

    浅谈Spring单例Bean与单例模式的区别

    "浅谈Spring单例Bean与单例模式的区别" 本文主要介绍了Spring单例Bean与单例模式的区别,通过对比两者的定义、实现机制和应用场景,帮助读者更好地理解这两种概念的异同。 一、单例模式的定义和实现 单例模式是一...

    浅谈SpringMVC中Interceptor和Filter区别

    浅谈SpringMVC中Interceptor和Filter区别 SpringMVC中Interceptor和Filter是两个重要的概念,它们都是用来处理用户请求的,但它们有着不同的作用和实现机制。本文将详细介绍Interceptor和Filter的区别,帮助读者更...

    浅谈Spring中@Import注解的作用和使用

    @Import 注解的实现原理是通过 Java 的反射机制来实现的。Spring 框架会在容器启动时扫描所有@Configuration 注解的配置类,并将其注册到容器中。然后,在容器中找到了@Configuration 注解的配置类后,Spring 框架会...

    asp.net知识库

    也谈 ASP.NET 1.1 中 QueryString 的安全获取写法 ASP.NET运行模式:PageHandlerFactory 利用搜索引擎引用来高亮页面关键字 网站首页的自动语言切换 应用系统的多语言支持 (一) 应用系统的多语言支持 (二) 自动...

Global site tag (gtag.js) - Google Analytics