Java学习之反射

来源:互联网 发布:店面装修设计网站 知乎 编辑:程序博客网 时间:2024/06/05 06:36

一、概念

反射就是通过字节码文件对象去使用成员

例如:Student.java的字节码文件是Student.class,可以把这个字节码文件看成一个对象,这个对象就叫做字节码文件对象,对应的类是Class

二、获取字节码文件

(1)Object类的getClass()方法

(2)数据类型的静态class属性

(3)Class类的静态方法forName()

注意:平常写案例中使用第二种方便,实际开发中使用的是第三种,因为第三种接收的是一个字符串类型的参数,我们可以把这个参数作为配置文件的内容进行配置,这样就实现了一个变化的内容

代码:

public class ReflectDemo {public static void main(String[] args) throws Exception {//A:Object类的getClass()方法//由于所有类的父类都是Object所以可以直接使用实例调用方法Student s1 = new Student();Student s2 = new Student();//获取字节码文件对象Class c1 = s1.getClass();Class c2 = s2.getClass();//比较System.out.println(c1==c2);//true//通过这个字节码文件的对比,可以对静态同步方法中使用类的字节码文件做为锁调用进行解释,因为就算创建多个对象,但是这个类的字节码文件对象是不变的//B:数据类型的静态class属性Class c3 = Student.class;System.out.println(c2==c3);//true//C:Class类的静态方法forName()//public static Class<?> forName(String className),在这里所说的类名是全类名(带包名的类名)Class c4 = Class.forName("com.edu_01.Student");System.out.println(c3==c4);//true}}
三、使用步骤

首先创建class字节码文件对象,然后去得到对应的成员对象,然后通过该成员的对象调用方法使用

成员变量:Field

构造方法:Constructor

成员方法:Method

四、使用

1、通过反射获取构造方法

需要的类:

package com.edu_01;public class Student {String name;private int age;public String address;public Student() {super();}Student(String name){this.name = name;}protected Student(String name, int age){this.name = name;this.age = age;}private Student(String name, int age,String address) {super();this.name = name;this.age = age;this.address = address;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void run(){System.out.println("run");}void function(String name){System.out.println(name);}private void show(String name,int age){System.out.println(name+"---"+age);}protected void show(String name,int age,String address){System.out.println(name+"---"+age+"---"+address);}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + ", address="+ address + "]";}}


1.通过反射获取构造方法

public Constructor[] getConstructors() 获取公共的构造方法

public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有)

public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造

public Constructor getDeclaredConstructor(Class<?>... parameterTypes) 根据构造参数获取指定构造(包括私有,但是私有在使用的时候需要取消访问限制)

2.通过反射获取构造方法并创建对象

 public T newInstance(Object... initargs)

import java.lang.reflect.Constructor;public class ReflectDemo {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c4 = Class.forName("com.edu_02.Student");//public Constructor[] getConstructors() 获取公共的构造方法Constructor[] cs = c4.getConstructors();for (Constructor c : cs) {System.out.println(c);}System.out.println("-----------------");// public Constructor[] getDeclaredConstructors() 获取所有的构造方法(包括私有)Constructor[] dc = c4.getDeclaredConstructors();for (Constructor c : dc) {System.out.println(c);}System.out.println("------------------");// public Constructor getConstructor(Class... parameterTypes) 根据构造参数获取公共的指定构造//使用字节码文件对象创建对象//获取无参构造Constructor cs2 = c4.getConstructor();System.out.println(cs2);//通过无参构造创建对象//public T newInstance(Object... initargs)Object s = cs2.newInstance();System.out.println(s);System.out.println("-----------------");//获取private修饰的构造方法// public Constructor getDeclaredConstructor(Class<?>... parameterTypes) // 根据构造参数获取指定构造(包括私有,但是私有在使用的时候需要取消访问限制)Constructor con = c4.getDeclaredConstructor(String.class);//在使用前要取消这个构造器对象所对应的访问权限检测con.setAccessible(true);Object obj = con.newInstance("风云");System.out.println(obj);System.out.println("----------------");//获取Protected修饰的构造方法Constructor con2 = c4.getDeclaredConstructor(String.class,int.class);//在使用前要取消这个构造器对象所对应的访问权限检测con2.setAccessible(true);Object obj2 = con2.newInstance("风云",20);System.out.println(obj2);}}
结果:

public com.edu_01.Student()-----------------private com.edu_01.Student(java.lang.String,int,java.lang.String)protected com.edu_01.Student(java.lang.String,int)com.edu_01.Student(java.lang.String)public com.edu_01.Student()------------------public com.edu_01.Student()Student [name=null, age=0, address=null]-----------------Student [name=风云, age=0, address=null]----------------Student [name=风云, age=20, address=null]

 3.通过反射获取成员变量并使用

public Field[] getFields()获取公有的成员变量

 public Field[] getDeclaredFields()获取全部的成员变量,包括私有

 public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有

 public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的

public void set(Object obj,Object value)给一个对象的一个字段设置一个值

import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class ReflectDemo {public static void main(String[] args) throws Exception {//获取字节码文件对象Class c4 = Class.forName("com.edu_02.Student");//获取无参构造方法Constructor con = c4.getConstructor();//创建对象Object obj = con.newInstance();// public Field[] getFields()获取公有的成员变量Field[] fie = c4.getFields();for (Field f : fie) {System.out.println(f);}System.out.println("================");//public Field[] getDeclaredFields()获取全部的成员变量,包括私有Field[] fie2 = c4.getDeclaredFields();for (Field f : fie2) {System.out.println(f);}System.out.println("================");//public Field getDeclaredField(String name) 传入变量名称返回指定的成员变量对象,包括私有Field fie3 = c4.getDeclaredField("name");System.out.println(fie3);System.out.println("================");// public Field getField(String name)传入变量名称返回指定的成员变量对象,仅可获取共有的Field fie4 = c4.getField("address");System.out.println(fie4);System.out.println("================");//public void set(Object obj,Object value)给一个对象的一个字段设置一个值fie4.setAccessible(true);fie4.set(obj, "风云");System.out.println(obj);}}
结果:

public java.lang.String com.edu_01.Student.address================java.lang.String com.edu_01.Student.nameprivate int com.edu_01.Student.agepublic java.lang.String com.edu_01.Student.address================java.lang.String com.edu_01.Student.name================public java.lang.String com.edu_01.Student.address================Student [name=null, age=0, address=风云]


 4.通过反射获取成员方法并使用

 public Method[] getMethods()获取所有公共成员方法

 public Method[] getDeclaredMethods()获取所有成员方法,包括私有

 public Method getMethod(String name, Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法

 public Method getDeclaredMethod(String name,Class<?>... parameterTypes)参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有

 Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数

import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class ReflectDemo {public static void main(String[] args) throws Exception {//创建字节码文件对象Class ref = Class.forName("com.edu_01.Student");//获取无参构造方法Constructor con = ref.getConstructor();//创建对象Object obj = con.newInstance();// public Method[] getMethods()获取所有公共成员方法//这种获取的还包括其父类方法Method[] md = ref.getMethods();for (Method m : md) {System.out.println(m);}System.out.println("================");//public Method[] getDeclaredMethods()获取所有成员方法,包括私有//这种获取的只是这个类的方法Method[] md2 = ref.getDeclaredMethods();for (Method m : md2) {System.out.println(m);}System.out.println("================");// public Method getMethod(String name, Class<?>... parameterTypes)  //参数一:方法名 参数二:方法参数类型.class 获取指定的公共方法Method md3 = ref.getMethod("run");System.out.println(md3);System.out.println("===============");// public Method getDeclaredMethod(String name,Class<?>... parameterTypes)  //参数一:方法名 参数二:方法参数类型.class 获取指定的方法,包括私有Method md4 = ref.getDeclaredMethod("show", String.class,int.class);md4.setAccessible(true);System.out.println(md4);System.out.println("==============");//Object invoke(Object obj, Object... args) 让某一个对象使用这个方法,并且传入参数Method md5 = ref.getDeclaredMethod("show", String.class,int.class,String.class);md5.setAccessible(true);md5.invoke(obj,"风云", 20,"澳门");System.out.println();}}
结果:

public void com.edu_01.Student.run()public java.lang.String com.edu_01.Student.toString()public int com.edu_01.Student.getAge()public void com.edu_01.Student.setAge(int)public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedExceptionpublic final native void java.lang.Object.wait(long) throws java.lang.InterruptedExceptionpublic final void java.lang.Object.wait() throws java.lang.InterruptedExceptionpublic boolean java.lang.Object.equals(java.lang.Object)public native int java.lang.Object.hashCode()public final native java.lang.Class java.lang.Object.getClass()public final native void java.lang.Object.notify()public final native void java.lang.Object.notifyAll()================public void com.edu_01.Student.run()public java.lang.String com.edu_01.Student.toString()void com.edu_01.Student.function(java.lang.String)private void com.edu_01.Student.show(java.lang.String,int)protected void com.edu_01.Student.show(java.lang.String,int,java.lang.String)public int com.edu_01.Student.getAge()public void com.edu_01.Student.setAge(int)================public void com.edu_01.Student.run()===============private void com.edu_01.Student.show(java.lang.String,int)==============风云---20---澳门




原创粉丝点击