java中的反射机制

来源:互联网 发布:tem和sem的区别知乎 编辑:程序博客网 时间:2024/04/29 03:26

<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 {@Testpublic 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);}@Testpublic 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);}@Testpublic 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+" ");}@Testpublic 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 {//反射类的方法@Testpublic 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);}@Testpublic 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]);}@Testpublic 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"));}@Testpublic 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[])@Testpublic 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 {@Testpublic 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);}//反射私有变量(字段)@Testpublic 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);}//反射静态变量(字段)@Testpublic 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


案例可能太长,按照本文最开始的那样就可以了。



0 0