zoukankan      html  css  js  c++  java
  • 通过反射动态使用Java类(转)

    一.已知一个类的名字及其class文件,如何使用此类?

    1.如果此类位于一个已打包的jar文件中,按如下方法调用:
    URL url = new URL("file:/E:/Work/Projects/Output/FrameWork.jar");
    URLClassLoader ul = new URLClassLoader(new URL[]{url});
    Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");
    Object obj = aClass.newInstance();

    注意的是URLClassLoader.loadClass()方法的参数要包括package的名字,例如这里面如果写成ProduceObject就是错误的。

    2.如果此类是一个class文件,位于一个文件夹中,按如下方法调用:
    首先要确认的是class的package的名字与目录名应该一致。
    URL url = new URL("file:/E:/Work/Projects/FrameWork/bin");
    URLClassLoader ul = new URLClassLoader(new URL[]{url});
    Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");
    Object obj = aClass.newInstance();
    这里面的URL的路径指到package名的上一层目录位置,例如这里如果写成file:/E:/Work/Projects/FrameWork/bin/com/hdpan/exercise/loader就是错误的

    Class这个类中还有许多的get方法可以使用。

    二.如何打印class中的所有方法?
    Method[] md = aClass.getDeclaredMethods();
    for (int i = 0; i < md.length; i++){
    System.out.println(md.getName());
    }
    md.getModifiers();
    md.getReturnType();
    md.getParameterTypes();
    md.getExceptionTypes();

    Method这个类中还有许多的属性可以get得到。

    如果有两个方法的Name是一样的,但是参数不一样:
    Method md = aClass.getMethod("setField1",new Class[]{Integer.TYPE});
    第一个参数是方法的名字,第二个参数是一个数组,如果是基本数据类型的话,使用其外覆类的类型,例如int使用Integer.Type,float使用Float.Type

    例如,如果类中是这样的定义的:
    public void setField1(int field1,String info) {
    this.field1 = field1;
    System.out.println(info);
    }

    那么在使用的时候:
    Method md = clas.getMethod("setField1",new Class[]{Integer.TYPE,String.class});

    三.如何调用class中的方法?
    调用方法:

    Object obj = aClass.newInstance();
    Method mds = aClass.getMethod("setField1",new Class[]{Integer.TYPE});
    mds.invoke(obj,new Object[]{new Integer(5)});

    对invoke方法,第一个参数是方法所在的对象,如果方法是static的,那么此处可以是null,如果方法不是static的,但是此处是Null的话将会出现NullPointerException
    第二参数是方法所需要的参数的对象数组,如果是基本数据类型的话,使用其外覆类的类型,例如int使用Integer.Type,float使用Float.Type

    例如,如果类中是这样的定义的::
    public void setField1(int field1,String info) {
    this.field1 = field1;
    System.out.println(info);
    }
    那么在使用的时候:
    Object obj = aClass.newInstance();
    Method md = aClass.getMethod("setField1",new Class[]{Integer.TYPE,String.class});
    md.invoke(obj,new Object[]{new Integer(5),"This is a Test"});

    如果想取得方法的返回值:
    public int getField1() {
    return field1;
    }

    那么在使用的时候:
    mds = aClass.getMethod("getField1",null);
    Integer integer = (Integer)mds.invoke(obj,null);
    System.out.println(integer.intValue());

    Method方法返回的类型是Object,根据具体的方法返回值类型,将其下溯到具体的类型。

    源程序:
    ProduceObject.java
    =================================
    //ProduceObject.java开始
    package com.hdpan.exercise.loader;

    public class ProduceObject {

    public int getField1() {
    return field1;
    }

    public void setField1(int field1) {
    this.field1 = field1;
    }
    public void setField1(int field1,String info) {
    this.field1 = field1;
    System.out.println(info);
    }

    public static double getField2() {
    return field2;
    }

    public static void setField2(double field2) {
    ProduceObject.field2 = field2;
    }
    private int field1;
    private static double field2;

    public static void main(String[] args) {
    }
    }
    //ProduceObject.java结束
    =========================

    TestLoader.java
    =========================
    //TestLoader.java开始
    package com.hdpan.exercise.loader;

    import java.lang.reflect.Method;
    import java.net.URL;
    import java.net.URLClassLoader;

    public class TestLoader {

    public static void main(String[] args) throws Exception {
    try {
    //URL url = new URL("file:/E:/Work/Projects/Output/FrameWork.jar");
    URL url = new URL("file:/E:/Work/Projects/FrameWork/bin/com/hdpan/exercise/loader");

    URLClassLoader ul = new URLClassLoader(new URL[]{url});

    //Class clas = ul.loadClass("ProduceObject");
    Class aClass = ul.loadClass("com.hdpan.exercise.loader.ProduceObject");

    Object obj = aClass.newInstance();
    Method mds = aClass.getMethod("setField1",new Class[]{Integer.TYPE,String.class});
    mds.invoke(obj,new Object[]{new Integer(5),"haha"});

    mds = aClass.getMethod("getField1",null);
    Integer integer = (Integer)mds.invoke(obj,null);
    System.out.println(integer.intValue());
    //System.out.println(((com.hdpan.exercise.loader.ProduceObject)obj).getField1());

    Method[] md = aClass.getDeclaredMethods();
    for (int i = 0; i < md.length; i++){
    System.out.println(md.getName());
    }

    } catch (Exception e) {
    System.out.println(e);
    }

    }
    }
    //TestLoader.java开始
  • 相关阅读:
    使用vue.js 引用阿里图标 --无法显示(报错)
    thinkphp5.0如何隐藏index.php入口文件
    thinkphp5.0--编写api,返回json格式
    小程序滑动问题(如何让底层不会跟着滑动)
    thinkphp5.0验证的封装
    git--提交代码
    小程序图片上传
    SVG分组和引用
    总结React写参数的几种方式
    React中使用echarts
  • 原文地址:https://www.cnblogs.com/chinatefl/p/1209862.html
Copyright © 2011-2022 走看看