<span> </span>
java中的反射机制是用来加载类,反射(解析)类中的字段,构造方法,成员方法。
1.Class c = Class.forName(类的全名(加包名))用来加载类
2.Constructor cs =c.getConstructor (参数类型(如String.class,null))
3.cs.newInstance(参数(如String,null))得到对象转换为加载的那个类型
4.这样子后构造函数就运行了
反射字段:
1.同上
2.Field f =c.getField(字段名(字符串))若为私有变量则用getDeclaredField然后f.setAccessable(ture)可获得许可访问私有变量
3.f,set(),f.get();
反射方法(和字段类似)
1.同上
2.Method m = c.getMethod(方法名,参数类型)若为私有方法则用getDeclaredMethod然后m.setAccessable(ture)可获得许可访问私有方法
3.m.invoke(对象名,参数)来运行这个方法
下面是案例:
Person.java
package com.java.test;
import java.io.InputStream;
import java.util.List;
public class Person {
public String name="XiaoMing";
private int age=10;
public static int num1=1222;
public Person(){
}
public Person(String name){
this.name=name;
}
public Person(String name ,int age ){
this.name = name;
this.age =age ;
}
private Person(List list){
}
public void aa1(){
System.out.println("无参数的aa1");
}
public Class[] aa1(String name,int password[]){
return new Class[]{String.class};
}
private void aa1(InputStream in){
System.out.println(in);
}
public static void aa1(int num){
System.out.println(num);
}
public static void main (String args[]){
System.out.println("this is a main method");
}
}
demo1.java(反射成员方法)
package com.java.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
//反射主要是加载类,解析成员方法,构造函数,成员变量
//newInstance(参数,参数,。。。)要让这个方法能运行
//类中必须含有无参的构造函数
public class Demo1 {
@Test
public void test1() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
//加载类
Class<?> clazz = Class.forName("com.java.test.Person");
//得到加载的类的某个构造函数
Constructor<?> c = clazz.getConstructor(null);
//根据加载到的构造函数创建一个 对象newInstance(object)
//强转成Person类
Person p =(Person) c.newInstance(null);
System.out.println(p.name);
}
@Test
public void test2() throws Exception{
//加载类
Class<?> clazz = Class.forName("com.java.test.Person");
//得到构造函数,参数为class类型
Constructor c = clazz.getConstructor(String.class);
//创建一个对象,参数为普通数据类行
Person p = (Person)c.newInstance("xxxxx");
System.out.println(p.name);
}
@Test
public void test3() throws Exception{
//加载类
Class<?> clazz = Class.forName("com.java.test.Person");
//得到构造函数,参数为class类型
Constructor c = clazz.getConstructor(String.class,int.class);
//创建一个对象,参数为普通数据类行
Person p = (Person)c.newInstance("xxxxx",20);
System.out.println(p.name+" ");
}
@Test
public void test4() throws Exception{
//加载类
Class<?> clazz = Class.forName("com.java.test.Person");
//得到构造函数,参数为class类型
Constructor c = clazz.getConstructor(List.class);
//暴力反射(私有的构造方法不能被外界访问,但是利用反射机制可以)
c.setAccessible(true);
//创建一个对象,参数为普通数据类行
Person p = (Person)c.newInstance(new ArrayList());
System.out.println(p.name);
}
}
运行结果:
XiaoMing
xxxxx
xxxxx
Demo2.java(反射成员方法)
package com.java.test;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo2 {
//反射类的方法
@Test
public void test1() throws Exception{
//实例化一个对象
Person p = new Person();
//加载类(异常)
Class clazz = Class.forName("com.java.test.Person");
//得到这个方法(共有的)
Method m = clazz.getMethod("aa1", null);
//让方法运行起来(让那个对象运行,参数是多少)
m.invoke(p, null);
}
@Test
public void test2() throws Exception{
//实例化一个对象
Person p = new Person();
//加载类(异常)
Class clazz = Class.forName("com.java.test.Person");
//得到这个方法
Method m = clazz.getMethod("aa1", String.class,int[].class);
//让方法运行起来(让那个对象运行,参数是多少)
Class cs[]=(Class[])m.invoke(p, "大熊",new int[]{1,2,3});
System.out.println(cs[0]);
}
@Test
public void test3() throws Exception{
//实例化一个对象
Person p = new Person();
//加载类(异常)
Class clazz = Class.forName("com.java.test.Person");
//得到这个方法(getDeclaredMethod是得到私有方法)
Method m = clazz.getDeclaredMethod("aa1", InputStream.class);
//让方法运行起来(让那个对象运行,参数是多少)
m.setAccessible(true);
m.invoke(p, new FileInputStream("c:\\1.txt"));
}
@Test
public void test4() throws Exception{
//实例化一个对象
//Person p = new Person();
//加载类(异常)
Class clazz = Class.forName("com.java.test.Person");
//得到这个方法
Method m = clazz.getMethod("aa1", int.class);
//让方法运行起来(让那个对象运行,参数是多少)
m.invoke(null, 20);
}
//反射类的主方法public static void main(String args[])
@Test
public void test5() throws Exception{
//实例化一个对象
//Person p = new Person();
//加载类(异常)
Class clazz = Class.forName("com.java.test.Person");
//得到这个方法
Method m = clazz.getMethod("main", String[].class);
//让方法运行起来(让那个对象运行,参数是多少)
m.invoke(null, (Object)new String[]{"Person"});
/**
* 如果是new String 参数的话
* jdk1.5以上(null,object ...obj);可变参数
* jdk1.4(null,object object[]);没有可变参数为object数组
* (数组)new String[]{"1","2","3"}会被拆成string a,string b,String c
* 然后调用main(String 1,String 2,String 3);无此方法,故错误
* 将其转化为object类型不会拆,既保持1.5又保持1.4
* 可变参数可传入数组,object数组当然ok啦
*/
}
}
运行结果
无参数的aa1
class java.lang.String
java.io.FileInputStream@544fe44c
20
this is a main method
Demo3.java(反射字段)
package com.java.test;
import java.lang.reflect.Field;
import org.junit.Test;
public class Demo3 {
@Test
public void test() throws Exception{
Person p = new Person();
Class clazz = Class.forName("com.java.test.Person");
Field f = clazz.getField("name");
/*String name = (String )f.get(p);
System.out.println(name);*/
//获取字段的值
Object value =f.get(p);
//获取字段的类型
Class type = f.getType();
if(type.equals(String.class)){
String svalue = (String) value;
System.out.println(svalue);
}
//给字段赋值
f.set(p, "LuLei");
System.out.println(p.name);
}
//反射私有变量(字段)
@Test
public void test2() throws Exception{
Person p= new Person();
Class clazz = Class.forName("com.java.test.Person");
Field f = clazz.getDeclaredField("age");
f.setAccessible(true);
int age = (int )f.get(p);
System.out.println(age);
}
//反射静态变量(字段)
@Test
public void test3() throws Exception{
Person p= new Person();
Class clazz = Class.forName("com.java.test.Person");
Field f = clazz.getField("num1");
int age = (int )f.get(p);
System.out.println(age);
}
}
运行结果:
XiaoMing
LuLei
10
1222
案例可能太长,按照本文最开始的那样就可以了。