java f反射_java反射机制[基础学习]
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反射机制[基础学习]相关推荐
- java f反射_java反射机制
反射定义 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为jav ...
- Java的反射作用_java反射机制的作用与优点
java的反射机制就是增加程序的灵活性,避免将程序写死到代码里, 例如: 实例化一个 person()对象, 不使用反射, new person(); 如果想变成 实例化 其他类, 那么必须修改源代码 ...
- java映射理解_Java反射的理解
Java反射的理解 反射之中包含了一个「反」字,所以想要解释反射就必须先从「正」开始解释. 一般情况下,我们使用某个类时必定知道它是什么类,是用来做什么的.于是我们直接对这个类进行实例化,之后使用这个 ...
- 零基础学java靠谱吗_零基础学习Java靠谱吗?
零基础学习Java靠谱吗?作为信息时代的当下,我们看到太多"掌握XX技能,轻松月薪3万"."年薪30万,这个技能你必须懂得"."价值X万的写简历秘籍& ...
- 搞java不细心_Java 2 (基础总结)
注:Java采用Unicode符号集,每个字符占2个字节,无论英文还是中文还是其他字符. 标识符 为变量.类或方法起的名称 以字母,下划线.或者$符号开头 由字母.数字.下划线或者$符号开头 区分大小 ...
- java 抛出异常效率_Java异常处理机制
与C++.python,Ruby一样,Java也有一个异常处理机制,当程序出现异常时,系统会自动生成一个Exception对象通知程序去处理.之所以这样设计目的在于使程序有更好的容错性和可读性,实现业 ...
- java 求正割_Java 反射机制详解
动态语言 动态语言,是指程序在运行时可以改变其结构:新的函数可以被引进,已有的函数可以被删除等在结构上的变化.比如众所周知的ECMAScript(JavaScript)便是一个动态语言.除此之外如Ru ...
- java什么时候用反射_Java反射机制使用场景
1 import java.io.*;2 importjava.util.Properties;3 4 /*问题描述:存在一个主板--已经定义好,不想修改其代码,还想在主板上面增加一些其他功能?5 * ...
- java class 使用_Java反射机制(Class类的使用)
1:通过无参构造实例化对象 package cn.itcast; /* * 通过无参构造实例化对象 * 通过Class类本身实例化对象,使用newInstance方法 * 需要注意的是:实例化类中存在 ...
最新文章
- Win2008上.NET4.0部署出错HTTP 错误 500.21 - Internal Server Error的解决方法
- SD-销售订单中装运点确认
- python opencv 如何给图片添加文字?cv2.putText() PIL
- python怎么输入文件数据库_python学习日记——文件及数据库
- spring-security问题记录
- 解决ftp的pasv模式下iptables设置问题
- 详述MySQL事务的实现原理
- 给apm换一个软件源
- 六大方法来对付网站出现的负面信息
- 刷排名优优软件_QQ群排名技术原理
- 将C盘里的Users文件夹移动到D盘
- python 爬取中国裁判文书网 + 破解字体 JS 加密
- 微信视频号视频如何下载保存?教你批量下载保存视频号视频到手机相册
- 计算机锁屏之后QQ音乐停止播放了,MAC电脑如何在息屏状态下让QQ音乐能继续播放音乐...
- 2022年最新个人免签易支付源码网站对接支付教程
- 关于java中输出流flush()方法
- 企业级 zabbix 监控项目实战
- 关于对象的construct与destruct
- 【P28】Enjoy The jFET 超简分立耳放
- 计算机网络分层及原理
热门文章
- 分享5个免费的在线 SQL 数据库环境,简直太方便了!
- 你没见过Java台式计算机和Java操作系统吧
- HTTP协议的挑战者:RSocket
- 死磕Java并发:深入分析ThreadLocal
- mysql所有的编码_MySQL 批量修改数据表编码及字符集
- libstdc++.so, needed by ../../../rknn_api/arm64-v8a/librknn_api.so, not found
- Python 自动给人脸 戴口罩
- 3rd_party/flatbuffers/tmp/flatc: No such file or directory
- Re-ID新方法VPM
- flask简单的登录demo