本篇文章为在工作中使用JAVA反射的经验总结,也可以说是一些小技巧,以后学会新的小技巧,会不断更新。本文不准备讨论JAVA反射的机制,网上有很多,大家随便google一下就可以了。

在开始之前,我先定义一个测试类Student,代码如下:

package chb.test.reflect;

public class Student {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} public static void hi(int age,String name){
System.out.println("大家好,我叫"+name+",今年"+age+"岁");
}
}

一、JAVA反射的常规使用步骤

反射调用一般分为3个步骤:

  • 得到要调用类的class
  • 得到要调用的类中的方法(Method)
  • 方法调用(invoke)

代码示例:

Class cls = Class.forName("chb.test.reflect.Student");
Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});
m.invoke(cls.newInstance(),20,"chb");

二、方法调用中的参数类型

在方法调用中,参数类型必须正确,这里需要注意的是不能使用包装类替换基本类型,比如不能使用Integer.class代替int.class。

如我要调用Student的setAge方法,下面的调用是正确的:

Class cls = Class.forName("chb.test.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",int.class);
setMethod.invoke(cls.newInstance(), 15);

而如果我们用Integer.class替代int.class就会出错,如:

Class cls = Class.forName("chb.test.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
setMethod.invoke(cls.newInstance(), 15);

jvm会报出如下异常:

java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)
at java.lang.Class.getDeclaredMethod(Unknown Source)
at chb.test.reflect.TestClass.testReflect(TestClass.java:23)

三、static方法的反射调用

static方法调用时,不必得到对象示例,如下:

Class cls = Class.forName("chb.test.reflect.Student");
Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);
staticMethod.invoke(cls,20,"chb");//这里不需要newInstance
//staticMethod.invoke(cls.newInstance(),20,"chb");

四、private的成员变量赋值

如果直接通过反射给类的private成员变量赋值,是不允许的,这时我们可以通过setAccessible方法解决。代码示例:

Class cls = Class.forName("chb.test.reflect.Student");
Object student = cls.newInstance();//得到一个实例
Field field = cls.getDeclaredField("age");
field.set(student, 10);
System.out.println(field.get(student));

运行如上代码,系统会报出如下异常:

java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)
at java.lang.reflect.Field.doSecurityCheck(Unknown Source)
at java.lang.reflect.Field.getFieldAccessor(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at chb.test.reflect.TestClass.testReflect(TestClass.java:20)

解决方法:

Class cls = Class.forName("chb.test.reflect.Student");
Object student = cls.newInstance();
Field field = cls.getDeclaredField("age");
field.setAccessible(true);//设置允许访问
field.set(student, 10);
System.out.println(field.get(student));

其实,在某些场合下(类中有get,set方法),可以先反射调用set方法,再反射调用get方法达到如上效果,代码示例:

Class cls = Class.forName("chb.test.reflect.Student");
Object student = cls.newInstance(); Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);
setMethod.invoke(student, 15);//调用set方法 Method getMethod = cls.getDeclaredMethod("getAge");
System.out.println(getMethod.invoke(student));//再调用get方法

JAVA反射使用手记的更多相关文章

  1. 通过Java反射调用方法

    这是个测试用的例子,通过反射调用对象的方法.     TestRef.java import java.lang.reflect.Method; import java.lang.reflect.In ...

  2. 第28章 java反射机制

    java反射机制 1.类加载机制 1.1.jvm和类 运行Java程序:java 带有main方法的类名 之后java会启动jvm,并加载字节码(字节码就是一个类在内存空间的状态) 当调用java命令 ...

  3. Java反射机制

    Java反射机制 一:什么事反射机制 简单地说,就是程序运行时能够通过反射的到类的所有信息,只需要获得类名,方法名,属性名. 二:为什么要用反射:     静态编译:在编译时确定类型,绑定对象,即通过 ...

  4. java反射(基础了解)

    package cn.itcast_01; /** *Person类 */ public class Person {    /** 姓名 */    private String name;     ...

  5. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  6. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

  7. java反射学习之二万能EXCEL导出

    一.EXCEL导出的实现过程 假设有一个对象的集合,现在需要将此集合内的所有对象导出到EXCEL中,对象有N个属性:那么我们实现的方式是这样的: 循环这个集合,在循环集合中某个对象的所有属性,将这个对 ...

  8. java反射学习之一反射机制概述

    一.反射机制背景概述 1.反射(reflection)是java被视为动态语言的一个关键性质 2.反射机制指的是程序在运行时能获取任何类的内部所有信息 二.反射机制实现功能概述 1.只要给定类的全名, ...

  9. java反射 之 反射基础

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

随机推荐

  1. NoSql数据库 设计上面的一些心得

    NoSql数据库这个概念听闻许久了,也陆续看到很多公司和产品都在使用,优缺点似乎都被分析的清清楚楚.但我心里一直存有一个疑惑,它的出现究竟是为了解决什么问题? 用户信息表,书籍信息表,用户为书籍打分信 ...

  2. nhibernate 比较运算符

    比较运算符 HQL运算符 QBC运算符 含义 = Restrictions.eq() 等于 <> Restrictions.not(Exprission.eq()) 不等于 > Re ...

  3. CodeForces 805B 3-palindrome

    构造. $bbaabbaabbaa......$输出前$n$个即可,这样不需要用到$c$,而且任意相邻三个都不会是回文. #include <cstdio> #include <cm ...

  4. 洛谷P2408 不同字串个数 [后缀数组]

    题目传送门 不同字串个数 题目背景 因为NOI被虐傻了,蒟蒻的YJQ准备来学习一下字符串,于是它碰到了这样一道题: 题目描述 给你一个长为N的字符串,求不同的子串的个数 我们定义两个子串不同,当且仅当 ...

  5. hibernate for循环执行添加操作出错问题

    操作数据库使用hibernate框架 hibernate插入对象的时候,对于id唯一,数据库设置为自增的时候执行完操作后会将id赋予该对象 再次插入就会出现问题. 由于session缓存,得再研究下.

  6. 深入理解javascript作用域系列第四篇

    前面的话 尽管函数作用域是最常见的作用域单元,也是现行大多数javascript最普遍的设计方法,但其他类型的作用域单元也是存在的,并且通过使用其他类型的作用域单元甚至可以实现维护起来更加优秀.简洁的 ...

  7. hibernate-release-4.3.11.Final资源包介绍

    资源下载 hibernate-release-4.3.11.Final documentation 包  相关文档 lib  相关jar包 required --开发中必须要加入的包 optional ...

  8. 【BZOJ 3289】 3289: Mato的文件管理 (莫队)

    3289: Mato的文件管理 Time Limit: 40 Sec  Memory Limit: 128 MBSubmit: 2819  Solved: 1185 Description Mato同 ...

  9. android studio 可以汉化的 文件 地方

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 汉化包 百度云盘 下载地址:https://pan.baidu.com/s/1pLjwy ...

  10. [jzyzoj2021]lca模板题

    查找最近公共祖先...我也不知道这东西有什么用,在线写法,非常之慢.... 存代码 #include<cstdio> #include<iostream> #include&l ...