Java之反射
Posted 嫩不嫩上天
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java之反射相关的知识,希望对你有一定的参考价值。
目录
1.什么是反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的法的功能称为java语言的反射机制。
2.反射机制有什么用
通过java语言中的反射机制可以操作字节码文件(可以读和修改字节码文件。)
通过反射机制可以操作代码片段。(class文件。)
3.Class类对象的三种实例化模式
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
Class类对象的三种实例化模式:
以下分别举例实现:
1.getClass()方法:
public final native Class<?> getClass()
范例:调用getClass()方法
import java.util.Date;
public class test
public static void main(String[] args)
Date date=new Date();
System.out.println(date.getClass());
结果:找到对应的类
2.类.class
范例:通过类名找对应的class 文件
import java.util.Date;
public class test
public static void main(String[] args) throws Exception
System.out.println(Date.class);
结果:
3.使用Class类提供的方法:public static Class forName(String className) throws ClassNotFoundException
范例:使用Class.forName()方法
package 反射;
import java.lang.Class;
public class test
public static void main(String[] args) throws Exception
Class<?> date =Class.forName("java.util.Date");
System.out.println(date);
结果:
4. 通过反射实例化对象
以上事例中可以看出除了getClass()方法会实例化对象之外,其他的俩种不会产生实例化对象,所以取得Class类对象的一个最直接的好处就是通过反射实例化对象,该方法为:
对象.newInstance()
注:newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以。
否则会抛出java.lang.InstantiationException
异常。
范例:
package 反射;
import java.lang.Class;
import java.util.Date;
public class test
public static void main(String[] args) throws Exception
//通过反射机制,获取Class,通过Class来实例化对象
Class<?> cl=Class.forName("java.util.Date");
//newInstance() 这个方法会调用Date这个类的无参数构造方法,完成对象的创建。
// 重点是:newInstance()调用的是无参构造,必须保证无参构造是存在的!
Object object=cl.newInstance();
System.out.println(object);
5.反射主要使用的种类
5.1Class类方法:
举例常见的几种方法:
1.获取类名
import 新特性.泛型.泛型接口.test;
public class demo
public static void main(String[] args) throws Exception
Class<?> cl=test.class;
System.out.println(cl.getName());
System.out.println(cl.getSimpleName());
结果:
2.获取类中的所有方法(重要)
import java.lang.reflect.Method;
import 新特性.泛型.泛型类方法.test;
public class getMethod
public static void main(String[] args) throws Exception
//通过反射机制,获取Class,通过Class来实例化对象
Class<?> cl = test.class;
//通过getMethods方法获取所有public修饰的普通方法
Method[] methods = cl.getMethods();
for (Method i : methods)
System.out.println(i.getName());
System.out.println();
//通过getDeclaredMethods返回类中所有的实例方法
Method[] methods1 = cl.getDeclaredMethods();
for (Method i : methods1)
System.out.println(i.getName());
5.2Field类方法
范例:
import java.lang.reflect.Field;
class Person
public String name;
public int age;
class Student extends Person
public String school;
public class getField
public static void main(String[] args) throws Exception
Class<?> cl= Student.class;1
Field[] fields=cl.getFields();
//返回public修饰的所有属性
for (Field field:fields)
System.out.println(field.getName());
System.out.println();
//返回本类中的所有属性
Field[] fie=cl.getDeclaredFields();
for (Field field:fie)
System.out.println(field.getName());
//通过反射操作属性-----set/get方法
Object obj=cl.newInstance();
Field getFid=cl.getDeclaredField("school");
getFid.set(obj,"华润希望小学");
System.out.println(getFid.get(obj));
结果:
5.3:Method方法
重点getMethod()方法和invoke方法
范例:在有了反射机制处理之后,即使没有明确的Person类型对象(依然需要实例化对象,Object对象描述,所有 的普通方法必须在有实例化对象之后才可以进行调用)。就可以通过反射调用。通过反射去调用setter,getter方法
Method getMethod(String name,Class...parameterTypes)
name: method的名称
parameterTypes:method的参数类型的列表(参数顺序需按声明method时的参数列表排列)
返回:符合method名称和参数的method对象
抛出错误:NoSuchMethodException (没有找到所要查询的Method对象或Method名称为“<init>”或“<clinit>”) NullPointerException (所要查询的Method对象的名称为null) SecurityException(调用的类或其父类没有调用权限)
invoke方法:
作用:调用包装在当前Method对象中的方法。
原型:Object invoke(Object obj,Object...args) 参数解释:obj:实例化后的对象 args:用于方法调用的参数
返回:根据obj和args调用的方法的返回值
抛出错误:IllegalAccessException(Method对象强制Java语言执行控制或无权访问obj对象) IllegalArgumentException(方法是实例化方法,而指定需要调用的对象并不是实例化后的类或接口)
import java.lang.reflect.Method;
class Person
private String name;
private int age;
private String sex;
public int getAge()
return age;
public String getName()
return name;
public String getSex()
return sex;
public void setAge(int age)
this.age = age;
public void setSex(String sex)
this.sex = sex;
public void setName(String name)
this.name = name;
public class getMethod
public static void main(String[] args) throws Exception
//通过类名.class获取class对象
Class<?> cl=Person.class;
//实例划对象
Object o=cl.newInstance();
//通过getMethon方法取得setName这个方法的实例化对象,方法名称与参数类型
Method setMethod=cl.getMethod("setName", String.class);
//通过invoke调用方法
setMethod.invoke(o,"wangyang");
Method getMethod=cl.getMethod("getName");
Object result=getMethod.invoke(o);
System.out.println(result);
此类操作的好处是:不再局限于某一具体类型的对象,而是可以通过Object类型进行所有类的方法调用。这个操作 必须掌握.
可参考Java反射(超详细!)_一只小菜鸡-CSDN博客_java反射
Java反射之剖析方法
继上篇反射构造函数后,今剖析函数方法。
要通过反射执行方法:
1、可以先反射出类或构造函数,创建实例对象,通过对象调用方法(反射通过构造函数创建对象参见上篇)。
2、可以通过类反射出方法,传入关联对象,从而实现对象调用方法。
以下是一个简单测试类:
包含两个文件:
1、Person.java,用于反射操作
2、Deom:Demo_MtdRft.java,反射的测试代码
测试的情况包括:1、公有方法,2、私有方法,3、无参数方法,4、有参数方法,5静态方法
下面是两个测试代码文件:
Person.java

1 package cn.rt.gwq; 2 3 import java.util.List; 4 5 public class Person { 6 7 public String value = "public value"; 8 9 /** 10 *无参数构造函数 11 */ 12 public Person() { 13 System.out.println("no params constructor"); 14 } 15 16 /** 17 * 一个参数的构造函数 18 * @param name 19 */ 20 public Person(String name) { 21 System.out.println("string name constructor"); 22 value = "change the value : "+name; 23 } 24 25 /** 26 * 一个参数的构造函数 27 * @param age 28 */ 29 public Person(int age) { 30 System.out.println("int age constructor"); 31 value = "change the value : "+age; 32 } 33 34 /** 35 * 多个参数的构造函数 36 * @param usm 37 * @param pwd 38 */ 39 public Person(String usm,String pwd) { 40 System.out.println("String usm,String pwd constructor"); 41 value = "change the value : "+usm +":"+pwd; 42 } 43 44 /** 45 * 私有的构造函数 46 * @param list 47 */ 48 private Person(List list) { 49 System.out.println("List constructor"); 50 value = "change the value : "+list.toArray().toString(); 51 } 52 //////// 53 54 55 56 57 58 59 60 61 //////// 62 /** 63 *无参数方法 64 */ 65 public void eat(){ 66 System.out.println("eating soup..."); 67 } 68 69 /** 70 * 有参数方法 71 * @param food 72 */ 73 public void eat(String food){ 74 System.out.println(food + "is delicious..."); 75 } 76 77 /** 78 * 有返回值的方法 79 * @param food 80 * @return 81 */ 82 public String eat(String name,String food){ 83 System.out.println(food + "is good,"+name+", try it."); 84 return food; 85 } 86 87 /** 88 * 私有方法 89 */ 90 private void work(){ 91 System.out.println("I don‘t like to work."); 92 } 93 94 /** 95 * 静态方法 96 */ 97 public static void sleep(){ 98 System.out.println("I‘m sleeping ...."); 99 } 100 101 102 103 }
Demo_MtdRft.java

1 package cn.rt.gwq; 2 3 import java.lang.reflect.Method; 4 5 import org.junit.Test; 6 7 /** 8 * 反射方法的测试demo 9 * @author Administrator 10 * 11 */ 12 public class Demo_MtdRft { 13 14 /** 15 * 反射没有参数的公开方法 16 * @throws Exception 17 */ 18 @Test 19 public void test1() throws Exception{ 20 21 Person person = new Person(); 22 //加载类 23 Class clazz = Class.forName("cn.rt.gwq.Person"); 24 //获取方法 25 Method method = clazz.getMethod("eat", null); 26 //执行方法 27 method.invoke(person, null); 28 29 return; 30 31 } 32 33 /*** 34 * 反射带一个参数的方法 35 * @throws Exception 36 */ 37 @Test 38 public void test2() throws Exception{ 39 40 Person person = new Person(); 41 42 Class clazz = Class.forName("cn.rt.gwq.Person"); 43 Method method = clazz.getMethod("eat", String.class); 44 method.invoke(person, "fish"); 45 46 return; 47 48 } 49 50 /*** 51 * 反射有返回值的方法 52 * @throws Exception 53 */ 54 @Test 55 public void test3() throws Exception{ 56 57 Person person = new Person(); 58 59 Class clazz = Class.forName("cn.rt.gwq.Person"); 60 Method method = clazz.getMethod("eat", String.class,String.class); 61 String food = (String) method.invoke(person, "tom","fish"); 62 System.out.println("food :"+food); 63 64 return; 65 66 } 67 68 /** 69 * 反射私有方法 70 * @throws Exception 71 */ 72 @Test 73 public void test4() throws Exception{ 74 75 Person person = new Person(); 76 77 Class clazz = Class.forName("cn.rt.gwq.Person"); 78 //获取私有方法 79 Method method = clazz.getDeclaredMethod("work", null); 80 //强制在类外可自执行 81 method.setAccessible(true); 82 //执行 83 method.invoke(person, null); 84 85 return; 86 87 } 88 89 /** 90 * 反射静态方法 91 * @throws Exception 92 */ 93 @Test 94 public void test5() throws Exception{ 95 96 Person person = new Person(); 97 98 Class clazz = Class.forName("cn.rt.gwq.Person"); 99 //也可以用getMethod方法获取 100 Method method = clazz.getDeclaredMethod("sleep", null); 101 method.setAccessible(true); 102 method.invoke(person, null); 103 104 return; 105 106 } 107 108 109 }
以上是关于Java之反射的主要内容,如果未能解决你的问题,请参考以下文章
Java进阶之reflection(反射机制)——反射概念与基础