Java反射使用总结
来源:互联网 发布:cf易语言源码大全 编辑:程序博客网 时间:2024/05/17 22:03
一、概述
反射:指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。也就是可以获取正在运行的Java对象。
反射作为Java中一个强大的工具,不仅可以很方便创建灵活的代码,而且对一些其他第三方代码可以进行增强。
其主要功能主要有:
1、可以判断运行时对象所属的类
2、可以判断运行时对象所拥有的成员属性和方法
3、生成动态代理
光看概念有些晦涩,我们先说一个简单的应用反射的例子:
public class Item { private String id; private String name; private double price; public Item(String id, String name, double price) { this.id = id; this.name = name; this.price = price; } public String getId() { return id; } public String getName() { return name; } public double getPrice() { return price; }}
上面这部分代码不管出于什么目的,其成员属性只在new对象时接收,其他情况一律修改不了。我们可以通过反射来修改类的私有属性。
public static void main(String[] args) throws Exception { Item item = new Item("1", "a", 1.0); Field field = item.getClass().getDeclaredField("id"); field.setAccessible(true); field.set(item, "2"); System.out.println(item.getId()); // 2 }
运行可以发现,我们已经把其对象的id值更新到了2。
二、具体功能实现
1、获取类并创建其对象:反射中获取类通常有三种方法
Class clz1 = Class.forName("java.lang.String"); // 1.通过包和类名Class clz2 = String.class; // 2.直接通过类名String str = new String();Class clz3 = str.getClass(); // 3.根据对象(运行时类)clz1.newInstance();clz2.newInstance();
2、获取类的属性
3、获取类的方法
4、总结
- 反射里的Class, Field, Method, Constructor必须结合对象使用,除非是静态的。
- 获取非public对象须用类似getDeclaredMethod()而不是getMethod()。
- Field和Method都能设置accessible(true),之后能访问到私有权限。
三、一个简单的例子
下面是一个Person类,其中有两个私有属性id和name;拥有一个构造方法和一个私有方法print;
- 还有一个public内部类BaseInfo:含有两个私有属性nation和bloodType;拥有一个构造方法和一个私有方法print;
- 还有一个private内部类FamilyInfo:含有两个私有属性nativePlace和address,拥有一个构造方法和一个私有方法print。
由于FamilyInfo为私有的,因此为了可以初始化其属性,在Person中添加了一个私有属性,并在构造方法中对其进行了初始化。
public class Person { private String id; private String name; private FamilyInfo familyInfo; public Person(String id, String name) { this.id = id; this.name = name; this.familyInfo = this.new FamilyInfo("beijing", "beijing"); } private void print() { System.out.println("Person{id=" + id + ", name=" + name + "}"); } public class BaseInfo { private String nation; private String bloodType; public BaseInfo(String nation, String bloodType) { this.nation = nation; this.bloodType = bloodType; } private void print() { System.out.println("BaseInfo{nation=" + nation + ", bloodType=" + bloodType + "}"); } } private class FamilyInfo { private String nativePlace; // 籍贯 private String address; // 住址 private FamilyInfo(String nativePlace, String address) { this.nativePlace = nativePlace; this.address = address; } private void print() { System.out.println("FamilyInfo{nativePlace=" + nativePlace + ", address=" + address + "}"); } }}
下面的Main方法中,初始化了Person类,通过一个getFiledFromPerson()
方法打印出其私有属性、私有方法、内部类私有属性及方法。
public class Main { private static void getFiledFromPerson(Person person, Person.BaseInfo baseInfo) { try { // 获取外部类的私有属性 Field idField = person.getClass().getDeclaredField("id"); idField.setAccessible(true); String id = (String) idField.get(person); System.out.println("id:" + id); Field familyInfoField = person.getClass().getDeclaredField("familyInfo"); familyInfoField.setAccessible(true); Object familyInfo = familyInfoField.get(person); // 获取外部类的私有方法 Method printPersonMethod = person.getClass().getDeclaredMethod("print"); printPersonMethod.setAccessible(true); printPersonMethod.invoke(person); // 获取内部类的私有属性 Class baseInfoClz = Class.forName("demo.Person$BaseInfo"); Field nationField = baseInfoClz.getDeclaredField("nation"); nationField.setAccessible(true); String nation = (String) nationField.get(baseInfo); System.out.println("nation:" + nation); Class familyInfoClz = Class.forName("demo.Person$FamilyInfo"); Field field = familyInfoClz.getDeclaredField("address"); field.setAccessible(true); String address = (String) field.get(familyInfo); System.out.println("address:" + address); // 获取内部类的私有方法 Method printBaseInfoMethod = baseInfoClz.getDeclaredMethod("print"); printBaseInfoMethod.setAccessible(true); printBaseInfoMethod.invoke(baseInfo); Method printFamilyInfoMethod = familyInfoClz.getDeclaredMethod("print"); printFamilyInfoMethod.setAccessible(true); printFamilyInfoMethod.invoke(familyInfo); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Person person = new Person("1001", "John"); // 初始化Person以及默认FamilyInfo Person.BaseInfo baseInfo = person.new BaseInfo("han", "A"); // 初始化BaseInfo getFiledFromPerson(person, baseInfo); }}
阅读全文
0 0
- Java 反射 使用总结
- Java 反射 使用总结
- Java 反射 使用总结
- Java反射使用总结
- Java 反射总结和使用
- java 反射的一些使用总结
- java 基础之反射使用总结
- 【Java】Java反射总结
- 反射的使用总结
- 反射使用的总结
- c# 反射使用总结
- java反射总结
- java 反射 总结
- java 反射 总结
- java 反射 总结
- java 反射 总结
- java 反射总结
- JAVA 反射学习总结
- 设计模式
- Week10 53. Maximum Subarray
- 阶层相乘及相加
- 作业问题
- JQuery_基础选择器
- Java反射使用总结
- 命名污染与生命周期
- 1099
- 循环链表
- AIDL使用
- 6.18
- Hybrid APP的离线存储总结
- HTTP小常识
- GitLab使用总结