1.4 找出类的方法

找出一个类中定义了些什么方法,这是一个非常有价值也非常基础的 reflection 用法。下面的代码就实现了这一用法:

import java.lang.reflect.*;

public class method1 {

private int f1(Object p, int x) throws NullPointerException {

if (p == null)

throw new NullPointerException();

return x;

}

public static void main(String args[]) {

try {

Class cls = Class.forName("method1");

Method methlist[] = cls.getDeclaredMethods();

for (int i = 0; i < methlist.length; i++) {

Method m = methlist[i];

System.out.println("name = " + m.getName());

System.out.println("decl class = " + m.getDeclaringClass());

Class pvec[] = m.getParameterTypes();

for (int j = 0; j < pvec.length; j++)

System.out.println("param #" + j + " " + pvec[j]);

Class evec[] = m.getExceptionTypes();

for (int j = 0; j < evec.length; j++)

System.out.println("exc #" + j + " " + evec[j]);

System.out.println("return type = " + m.getReturnType());

System.out.println("-----");

}

} catch (Throwable e) {

System.err.println(e);

}

}

}

个程序首先取得 method1 类的描述,然后调用 getDeclaredMethods 来获取一系列的 Method

对象,它们分别描述了定义在类中的每一个方法,包括 public 方法、protected 方法、package 方法和 private

方法等。如果你在程序中使用 getMethods 来代替 getDeclaredMethods,你还能获得继承来的各个方法的信息。

取得了 Method 对象列表之后,要显示这些方法的参数类型、异常类型和返回值类型等就不难了。这些类型是基本类型还是类类型,都可以由描述类的对象按顺序给出。

输出的结果如下:

name = f1

decl class = class method1

param #0 class java.lang.Object

param #1 int

exc #0 class java.lang.NullPointerException

return type = int

-----

name = main

decl class = class method1

param #0 class [Ljava.lang.String;

return type = void

-----

1.5获取构造器信息

获取类构造器的用法与上述获取方法的用法类似,如:

import java.lang.reflect.*;

public class constructor1 {

public constructor1() {

}

protected constructor1(int i, double d) {

}

public static void main(String args[]) {

try {

Class cls = Class.forName("constructor1");

Constructor ctorlist[] = cls.getDeclaredConstructors();

for (int i = 0; i < ctorlist.length; i++) {

Constructor ct = ctorlist[i];

System.out.println("name = " + ct.getName());

System.out.println("decl class = " + ct.getDeclaringClass());

Class pvec[] = ct.getParameterTypes();

for (int j = 0; j < pvec.length; j++)

System.out.println("param #" + j + " " + pvec[j]);

Class evec[] = ct.getExceptionTypes();

for (int j = 0; j < evec.length; j++)

System.out.println("exc #" + j + " " + evec[j]);

System.out.println("-----");

}

} catch (Throwable e) {

System.err.println(e);

}

}

}

这个例子中没能获得返回类型的相关信息,那是因为构造器没有返回类型。

这个程序运行的结果是:

name = constructor1

decl class = class constructor1

-----

name = constructor1

decl class = class constructor1

param #0 int

param #1 double

-----

1.6获取类的字段(域)

找出一个类中定义了哪些数据字段也是可能的,下面的代码就在干这个事情:

例1:

import java.lang.reflect.*;

public class field1 {

private double d;

public static final int i = 37;

String s = "testing";

public static void main(String args[]) {

try {

Class cls = Class.forName("field1");

Field fieldlist[] = cls.getDeclaredFields();

for (int i = 0; i < fieldlist.length; i++) {

Field fld = fieldlist[i];

System.out.println("name = " + fld.getName());

System.out.println("decl class = " + fld.getDeclaringClass());

System.out.println("type = " + fld.getType());

int mod = fld.getModifiers();

System.out.println("modifiers = " + Modifier.toString(mod));

System.out.println("-----");

}

} catch (Throwable e) {

System.err.println(e);

}

}

}

个例子和前面那个例子非常相似。例中使用了一个新东西 Modifier,它也是一个 reflection

类,用来描述字段成员的修饰语,如“private int”。这些修饰语自身由整数描述,而且使用 Modifier.toString

来返回以“官方”顺序排列的字符串描述 (如“static”在“final”之前)。这个程序的输出是:

name = d

decl class = class field1

type = double

modifiers = private

-----

name = i

decl class = class field1

type = int

modifiers = public static final

-----

name = s

decl class = class field1

type = class java.lang.String

modifiers =

-----

例2:

import java.lang.reflect.*;

import java.awt.*;

class SampleGet {

public static void main(String[] args) {

Rectangle r = new Rectangle(100, 325);

printHeight(r);

}

static void printHeight(Rectangle r) {

Field heightField;

Integer heightValue;

Class c = r.getClass();

try {

heightField = c.getField("height");//取得height这个变量

heightValue = (Integer) heightField.get(r);//取得height这个变量的值

System.out.println("Height: " + heightValue.toString());

} catch (NoSuchFieldException e) {

System.out.println(e);

} catch (SecurityException e) {

System.out.println(e);

} catch (IllegalAccessException e) {

System.out.println(e);

}

}

}

输出:Height:325

和获取方法的情况一下,获取字段的时候也可以只取得在当前类中申明了的字段信息 (getDeclaredFields),或者也可以取得父类中定义的字段 (getFields) 。

1.7 根据方法的名称来执行方法

文本到这里,所举的例子无一例外都与如何获取类的信息有关。我们也可以用 reflection 来做一些其它的事情,比如执行一个指定了名称的方法。下面的示例演示了这一操作:

例1:

import java.lang.reflect.*;

public class method2 {

public int add(int a, int b) {

return a + b;

}

public static void main(String args[]) {

try {

Class cls = Class.forName("method2");

Class partypes[] = new Class[2];

partypes[0] = Integer.TYPE;

partypes[1] = Integer.TYPE;

Method meth = cls.getMethod("add", partypes);

method2 methobj = new method2();

Object arglist[] = new Object[2];

arglist[0] = new Integer(37);

arglist[1] = new Integer(47);

Object retobj = meth.invoke(methobj, arglist);

Integer retval = (Integer) retobj;

System.out.println(retval.intvalue());

} catch (Throwable e) {

System.err.println(e);

}

}

}

假如一个程序在执行的某处的时候才知道需要执行某个方法,这个方法的名称是在程序的运行过程中指定的 (例如,JavaBean 开发环境中就会做这样的事),那么上面的程序演示了如何做到。

例中,getMethod 用于查找一个具有两个整型参数且名为 add 的方法。找到该方法并创建了相应的 Method

对象之后,在正确的对象实例中执行它。执行该方法的时候,需要提供一个参数列表,这在上例中是分别包装了整数 37 和 47 的两个 Integer

对象。执行方法的返回的同样是一个 Integer 对象,它封装了返回值 84。

例2:

import java.lang.reflect.Method;

//Base.java 抽象基类

//Son1.java 基类扩展1

//Son2.java 基类扩展2

//Util.java

//Base.java 抽象基类只是一个定义

abstract class Base {

}

//Son1.java 是已经实现的Base

class Son1 extends Base {

private int id;

private String name;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public void son1Method(String s) {

System.out.println(s);

}

}

// Son2.java 是已经实现的Base

class Son2 extends Base {

private int id;

private double salary;

public int getId() {

return id;

}

public void setId(int id) {

this.id = id;

}

public double getSalary() {

return salary;

}

public void setSalary(double salary) {

this.salary = salary;

}

}

// Util.java 演示了如何根据指定的类名,类字段名和所对应的数据,得到一个类的实例

public class Util {

// 此方法的最大好处是没有类名Son1,Son2 可以通过参数来指定,程序里面根本不用出现

public static Base utilDo(String beanName,

String methodName, String paraValue) {

Base base = null;

try {

Class cls = Class.forName(beanName);//生成类

base = (Base) cls.newInstance();//生成类的对象

Class[] paraTypes = new Class[] { String.class};

Method method = cls.getMethod(methodName, paraTypes);// fieldSetter为方法的名称;paraTypes为该方法的参数数组,要用类的形式

String[] paraValues = new String[] { paraValue };

method.invoke(base, paraValues);//执行方法

} catch (Throwable e) {

System.err.println(e);

}

return base;

}

public static void main(String[] args) {

Son1 son1 = (Son1) Util.utilDo("test.Reflection.Son1",

"setName", "I am son1");// 表示类的字符串一定要是类的“全类名”,这里是test.Reflection.Son1

System.out.println("son1.getName() :" + son1.getName());

}

}

java f反射_java反射机制[基础学习]相关推荐

  1. java f反射_java反射机制

    反射定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...

  2. Java的反射作用_java反射机制的作用与优点

    java的反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码 ...

  3. java映射理解_Java反射的理解

    Java反射的理解 反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释. 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的.于是我们直接对这个类进行实例化,之后使用这个 ...

  4. 零基础学java靠谱吗_零基础学习Java靠谱吗?

    零基础学习Java靠谱吗?作为信息时代的当下,我们看到太多"掌握XX技能,轻松月薪3万"."年薪30万,这个技能你必须懂得"."价值X万的写简历秘籍& ...

  5. 搞java不细心_Java 2 (基础总结)

    注:Java采用Unicode符号集,每个字符占2个字节,无论英文还是中文还是其他字符. 标识符 为变量.类或方法起的名称 以字母,下划线.或者$符号开头 由字母.数字.下划线或者$符号开头 区分大小 ...

  6. java 抛出异常效率_Java异常处理机制

    与C++.python,Ruby一样,Java也有一个异常处理机制,当程序出现异常时,系统会自动生成一个Exception对象通知程序去处理.之所以这样设计目的在于使程序有更好的容错性和可读性,实现业 ...

  7. java 求正割_Java 反射机制详解

    动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ru ...

  8. java什么时候用反射_Java反射机制使用场景

    1 import java.io.*;2 importjava.util.Properties;3 4 /*问题描述:存在一个主板--已经定义好,不想修改其代码,还想在主板上面增加一些其他功能?5 * ...

  9. java class 使用_Java反射机制(Class类的使用)

    1:通过无参构造实例化对象 package cn.itcast; /* * 通过无参构造实例化对象 * 通过Class类本身实例化对象,使用newInstance方法 * 需要注意的是:实例化类中存在 ...

最新文章

  1. Win2008上.NET4.0部署出错HTTP 错误 500.21 - Internal Server Error的解决方法
  2. SD-销售订单中装运点确认
  3. python opencv 如何给图片添加文字?cv2.putText() PIL
  4. python怎么输入文件数据库_python学习日记——文件及数据库
  5. spring-security问题记录
  6. 解决ftp的pasv模式下iptables设置问题
  7. 详述MySQL事务的实现原理
  8. 给apm换一个软件源
  9. 六大方法来对付网站出现的负面信息
  10. 刷排名优优软件_QQ群排名技术原理
  11. 将C盘里的Users文件夹移动到D盘
  12. python 爬取中国裁判文书网 + 破解字体 JS 加密
  13. 微信视频号视频如何下载保存?教你批量下载保存视频号视频到手机相册
  14. 计算机锁屏之后QQ音乐停止播放了,MAC电脑如何在息屏状态下让QQ音乐能继续播放音乐...
  15. 2022年最新个人免签易支付源码网站对接支付教程
  16. 关于java中输出流flush()方法
  17. 企业级 zabbix 监控项目实战
  18. 关于对象的construct与destruct
  19. 【P28】Enjoy The jFET 超简分立耳放
  20. 计算机网络分层及原理

热门文章

  1. 分享5个免费的在线 SQL 数据库环境,简直太方便了!
  2. 你没见过Java台式计算机和Java操作系统吧
  3. HTTP协议的挑战者:RSocket
  4. 死磕Java并发:深入分析ThreadLocal
  5. mysql所有的编码_MySQL 批量修改数据表编码及字符集
  6. libstdc++.so, needed by ../../../rknn_api/arm64-v8a/librknn_api.so, not found
  7. Python 自动给人脸 戴口罩
  8. 3rd_party/flatbuffers/tmp/flatc: No such file or directory
  9. Re-ID新方法VPM
  10. flask简单的登录demo