Java动态加载一个类的几种方法以及invoke

来源:互联网 发布:大学生网络知识竞赛 编辑:程序博客网 时间:2024/06/14 21:16

一.加载一个类的几种方法

接口

IUser

package org.me.javaapp;/** * * @author Administrator */public interface IUser {    }

User.java

/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */package org.me.javaapp;public class User implements IUser{    private String  name;    private int  id;    /**     * @return the name     */    public String getName() {        return name;    }    /**     * @param name the name to set     */    public void setName(String name) {        this.name = name;    }    /**     * @return the id     */    public int getId() {        return id;    }    /**     * @param id the id to set     */    public void setId(int id) {        this.id = id;    }}

主类

    public static void main(String[] args) throws ClassNotFoundException{      try{            Class c1=Class.forName("org.me.javaapp.User");            Class c2=User.class;            Object o1=c1.newInstance();            Object o2=c2.newInstance();            User u1=new User();            Class c3=u1.getClass();                        /*            this.getClass.getClassLoader();            // 使用当前类的ClassLoader                          Thread.currentThread().getContextClassLoader();                        // 使用当前线程的ClassLoader                          ClassLoader.getSystemClassLoader();             // 使 用系统ClassLoader,即系统的入口点所使用的ClassLoader。(注意,system ClassLoader与根 ClassLoader并不一样。JVM下system ClassLoader通常为App ClassLoader)              */            ClassLoader clo=Thread.currentThread().getContextClassLoader();            Class c4=clo.loadClass("org.me.javaapp.User");                        Field[] fs = c1.getDeclaredFields();            for(Field field:fs){                  System.out.println("获得属性的修饰符,例如public,static等等 >>"+Modifier.toString(field.getModifiers()));                System.out.println("属性的类型的名字 >>"+field.getType());                System.out.println("属性的名字 >>"+field.getName());            }            Method[] ms = c1.getDeclaredMethods();            for(Method field:ms){                  System.out.println("获得方法的修饰符,例如public,static等等 >>"+Modifier.toString(field.getModifiers()));                System.out.println("方法的参数个数 >>"+field.getParameterCount());                System.out.println("方法的名字 >>"+field.getName());            }            System.out.println("c1的父类>>"+c1.getSuperclass());            Class[] cs=c1.getInterfaces();            for(Class field:cs){                  System.out.println("接口的名字 >>"+field.getName());            }            System.out.println(">>>>>>>>>>>");        }        catch (Exception ex){        System.out.println(ex.toString());        }    }

输出:

获得属性的修饰符,例如public,static等等 >>private
属性的类型的名字 >>class java.lang.String
属性的名字 >>name
获得属性的修饰符,例如public,static等等 >>private
属性的类型的名字 >>int
属性的名字 >>id
获得方法的修饰符,例如public,static等等 >>public
方法的参数个数 >>0
方法的名字 >>getName
获得方法的修饰符,例如public,static等等 >>public
方法的参数个数 >>0
方法的名字 >>getId
获得方法的修饰符,例如public,static等等 >>public
方法的参数个数 >>1
方法的名字 >>setName
获得方法的修饰符,例如public,static等等 >>public
方法的参数个数 >>1
方法的名字 >>setId
c1的父类>>class java.lang.Object
接口的名字 >>org.me.javaapp.IUser

参考:JAVA中的反射机制

获取方法,和构造方法,不再详细描述,只来看一下关键字:
方法关键字
含义
getDeclaredMethods()
获取所有的方法
getReturnType()
获得方法的放回类型
getParameterTypes()
获得方法的传入参数类型
getDeclaredMethod("方法名",参数类型.class,……)
获得特定的方法
 
 
构造方法关键字
含义
getDeclaredConstructors()
获取所有的构造方法
getDeclaredConstructor(参数类型.class,……)
获取特定的构造方法
 
 
父类和父接口
含义
getSuperclass()
获取某类的父类
getInterfaces()
获取某类实现的接口


ClassLoader 详解及用途

ClassLoader主要对类的请求提供服务,当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。


java中的反射总结 【举例不错,很全面】


二.Invoke

一个方法可以生成多个Method对象,但只有一个root对象,主要用于持有一个MethodAccessor对象,这个对象也可以认为一个方法只有一个,相当于是static的,因为Method的invoke是交给MethodAccessor执行的。

package org.me.javaapp;public class Child extends Person{        public void say(String s) {        System.out.println("Hello invork>>>"+s);    }        public void add(int a,int b) {        a+=b;        System.out.println("a+b="+a);    }}

invoke调用

package org.me.test;import java.lang.reflect.Method;import org.junit.Test;public class TestInvoke {    @Test    public void testSingleton() throws Exception {        Class<?> clz = Class.forName("org.me.javaapp.Child");        Object o = clz.newInstance();        Method m = clz.getMethod("add", int.class,int.class);        m.invoke(o, 1,2);        m = clz.getDeclaredMethod("say", String.class);        m.invoke(o,"http://blog.csdn.net/unix21/");    }}


参考:

java中的反射,invoke方法

getMethod方法第一个参数指定一个需要调用的方法名称
第二个参数是需要调用方法的参数类型列表,是参数类型!如无参数可以指定null。
参数必须和方法中一样int和Integer,double和Double被视为不同的类型。


反射中getMethods 与 getDeclaredMethods 的区别

public Method[] getMethods()返回某个类的所有公用(public)方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
public Method[] getDeclaredMethods()对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法

当然也包括它所实现接口的方法。


JAVA深入研究——Method的Invoke方法【非常深入,讲了实现细节】

可以看到Method.invoke()实际上并不是自己实现的反射调用逻辑,而是委托给sun.reflect.MethodAccessor来处理。 
每个实际的Java方法只有一个对应的Method对象作为root。这个root是不会暴露给用户的,而是每次在通过反射获取Method对象时新创建Method对象把root包装起来再给用户。
在第一次调用一个实际Java方法对应得Method对象的invoke()方法之前,实现调用逻辑的MethodAccessor对象还没创建;
等第一次调用时才新创建MethodAccessor并更新给root,然后调用MethodAccessor.invoke()真正完成反射调用。

java反射机制详解 及 Method.invoke解释

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。


三.Class<?>与Class

Class<?> clz = Class.forName("org.me.javaapp.Child");        Class clzz = Class.forName("org.me.javaapp.Child");        Object o = clzz.newInstance();        Method m = clz.getMethod("add", int.class,int.class);        m.invoke(o, 1,2);        m = clz.getDeclaredMethod("say", String.class);        m.invoke(o,"http://blog.csdn.net/unix21/");
效果是一样的。

0 0