Java 反射机制
来源:互联网 发布:java高内聚低耦合 编辑:程序博客网 时间:2024/05/22 08:24
反射
经常使用反射,但其实一直对反射没有一个较为深入的理解,今天就来整体梳理并且总结一下这个知识点。
概念:
反射是一种运行时获取,检测,访问类自身信息的能力。对于运行时的任意一个类,都能知道这个类的所有属性和方法;对于该类的任意一个对象,都能够调用它的任意方法和属性。这也是Java称为”动态语言”的原因。
用途:
- 运行时获取一个类的对象(只需知道类名即可);
- 运行时获取一个类的属性和方法(包括构造方法),包括它的父类信息;
- 运行时判断任意对象所属的类;
- 运行时调用任意一个对象的方法。
反射的这些功能的前提是本地存在需要的类。当通过反射与一个未知的对象打交道时,JVM只是简单的检查这个对象,看它属于哪个特定的类,在用这个类做其他事情之前必须加载哪个类的Class对象,因此,哪个类.class文件对于JVM来说必须是可获取的,要么在本地,要么通过网络获取。
与反射相关的API
java.lang.Classjava.lang.reflect
Class类与java.lang.reflect类一起封装了对java反射的支持,该类库包含了Field,Method,Constructor类,这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员,这样你就可以使用Constructor创建新的对象,用get(),set()方法读取和修改与Field对象关联的字段,用invoke()方法调用与Method关联的方法。还可以通过getField(), getMethods()和getConstructor()等方法返回表示字段,方法,构造器。这样,匿名对象的类信息就能在运行时被完全确定下来了,而在编译时不需要知道任何。
一个简单的例子
Person.java
public abstract class Person { private int mAge; Person(int age){ this.mAge = age; } public void setAge(int age){ this.mAge = age; } public abstract void dress();//穿衣}
doExam.java
public interface doExam { public void exam();}
Student.java
public class Student extends Person implements doExam { private String mGrade;//年级 public Student(int age){ super(age); } public Student(int age, String grade){ super(age); this.mGrade = grade; } public void setGrade(String grade){ mGrade = grade; } public String getGrade(){ return this.mGrade; } private void doHomework(boolean isDo){ if(isDo){ System.out.println("我要做家庭作业!"); }else{ System.out.println("我要去打LOL"); } } @Override public void dress() { System.out.println("myreflect.Student -----> 学生穿校服"); } @Override public void exam() {}}
下面是main方法,直接在main方法中做一些测试,这样看起来更加一目了然:
public class ReflectTest { public static void main(String[] args) throws Exception { getClassNameTest(); getConstructorTest(); getInterfacesTest(); constructorTest(); methodTest(); fieldTest(); } // 1. 获取类名 private static void getClassNameTest() throws ClassNotFoundException { System.out.println("-----------------getClassNameTest-----------------"); //方法一 Class studentClass = Class.forName("myreflect.Student"); System.out.println("getName = "+studentClass.getName()); //方法二 Class studentClass1 = Student.class; System.out.println("getName = "+studentClass1); //获取父类 Class superClass = studentClass.getSuperclass(); System.out.println("getSuperclass = "+superClass.getName()); } // 2. 获取构造方法 private static void getConstructorTest() throws ClassNotFoundException { System.out.println("-----------------getConstructorTest-----------------"); Class studentClass = Class.forName("myreflect.Student"); Constructor[] consList = studentClass.getDeclaredConstructors(); for(Constructor cons:consList){ System.out.println("Constructor = "+cons.getName()); } } // 3. 获取所有的接口 private static void getInterfacesTest() throws ClassNotFoundException { System.out.println("----------------getInterfacesTest------------------"); Class studentClass = Class.forName("myreflect.Student"); Class<?> interfaces[] = studentClass.getInterfaces(); System.out.println("studentClass实现的接口有:"); for (int i = 0; i < interfaces.length; i++) { System.out.println((i + 1) + ":" + interfaces[i].getName()); } } // 4. 通过反射实例化一个对象 private static void constructorTest() throws Exception { System.out.println("----------------constructorTest------------------"); Class studentClass = Class.forName("myreflect.Student"); Constructor<Student> cons = studentClass.getConstructor(int.class, String.class); Student student = cons.newInstance(15, "初三"); student.setAge(24); student.setGrade("研一"); System.out.println("student age = "+student.getAge()); System.out.println("student grade = "+student.getGrade()); } //修改属性字段 private static void fieldTest() throws Exception { System.out.println("----------------fieldTest------------------"); Student student = new Student(15,"初三"); //获取父类,否则不能找到 Class personClass = Class.forName("myreflect.Person"); Field field = personClass.getDeclaredField("mAge"); field.setAccessible(true); field.set(student,100); System.out.println("student age = "+student.getAge()); } // 5. 操作方法 //操作普通方法可以使用 getMethod() ,该方法有两个参数:一个是方法名,一个是参数类型 //操作private类型方法需要使用 getDeclaredMethod(), 同样有两个参数,该方法有两个参数:一个是方法名,一个是参数类型 public static void methodTest() throws Exception { System.out.println("----------------methodTest------------------"); Student student = new Student(15,"初三"); Class studentClass = Class.forName("myreflect.Student"); Method method = studentClass.getMethod("setAge",int.class); method.invoke(student,22); System.out.println("修改后的对象为:student age = "+student.getAge()); Method method1 = studentClass.getDeclaredMethod("doHomework",boolean.class); method1.setAccessible(true); method1.invoke(student, false); }}
运行结果:
0 0
- 【反射】JAVA反射机制
- 【Java】JAVA反射机制
- Java 反射机制[Field反射]
- Java 反射机制[Method反射]
- Java反射机制笔记-反射机制
- java的反射机制
- Java的反射机制
- java反射机制详解!
- Java反射机制
- Java的反射机制
- java 反射机制--侯捷
- java反射机制
- java反射机制
- [候捷]Java反射机制
- java 反射机制
- java 反射机制初探
- 关于Java反射机制
- java反射机制
- sdut 2873 老--质价比
- 机器人运动范围
- 2016秋季,DDS 作业
- MySQL在命令窗口下不显示中文解决
- n皇后问题纯数组解法
- Java 反射机制
- iOS10适配问题
- 我的2016
- PHP THINKPHP ajax 轮训聊天室
- 我的奇葩考试经历
- 文章标题 Coderforces 689B : Mike and Shortcuts (BFS)
- chunk.size
- 操作系统之读者与写者问题
- OnboardSDK分析