- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java上乘武功入门--反射由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
public class Test { private static void changeStrValue(String str, char[] value) { // 只要执行魔法代码就可以达到下面的效果 // 施展魔法的代码稍后揭秘 } public static void main(String[] args) { changeStrValue("abc", new char[]{"d","e","f"}); String abc = "abc"; System.out.println("abc"); System.out.println(abc); System.out.println("abc".equals(abc)); }}
二当家的第一次看到这个执行结果觉得很有意思。明明应该是"abc"怎么就变成了"def"呢?
。
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键.
以上就是百科的解释。可能有点抽象,接着看二当家的给你 秀起来解释一下.
。
一般情况下,我们如果想要创建一个类的对象,应该要用到new关键字。但是像spring这样的框架,我们只需要配置类名,就可以得到类的实例。他是怎么做到的呢?
import java.util.List;public class Test { /** * 根据类名取得类实例 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param className * @param <T> * @return * @throws InstantiationException * @throws IllegalAccessException * @throws ClassNotFoundException */ public static <T> T getInstance(String className) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Class<T> clazz = (Class<T>) Class.forName(className); return clazz.newInstance(); } public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { List<String> list = getInstance("java.util.ArrayList"); list.add("abc"); list.add("def"); for (String v : list) { System.out.println(v); } }}
类名可以在程序运行中从配置文件获取,甚至是从网络获取,然后动态创建一个类的实例.
。
import java.util.ArrayList;public class Test { /** * 打印对象的类名 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param o */ public static void printClass(Object o) { System.out.printf(o.getClass().getName()); } public static void main(String[] args) { printClass(new ArrayList<>()); }}
。
我们一般要使用一个类,先要知道有什么方法和属性,先了解,后使用。但是像spring那样的框架为什么可以为我们自动注入呢?他怎么知道我们一个对象里有什么属性呢?
import java.lang.reflect.Field;import java.lang.reflect.Method;public class Test { /** * 打印类的属性 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param clazz */ public static void printFields(Class clazz) { System.out.println(clazz.getName() + "包含如下属性:"); for (Field f : clazz.getDeclaredFields()) { System.out.println(f); } } /** * 打印类的方法 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param clazz */ public static void printMethods(Class clazz) { System.out.println(clazz.getName() + "包含如下方法:"); for (Method m : clazz.getDeclaredMethods()) { System.out.println(m); } } public static void main(String[] args) { printFields(MyClass.class); printMethods(MyClass.class); }}class MyClass { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; }}
。
像spring这样的框架,即使一个属性是私有属性并且没有set方法,一样可以注入.
import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Test { /** * 调用一个对象的方法 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param o * @param methodName * @throws NoSuchMethodException * @throws InvocationTargetException * @throws IllegalAccessException */ public static void callMethod(Object o, String methodName) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Method m = o.getClass().getDeclaredMethod(methodName); m.setAccessible(true); m.invoke(o); } /** * 修改一个对象的属性 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param o * @param fieldName * @param value * @throws IllegalAccessException */ public static void changeFieldValue(Object o, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { Field f = o.getClass().getDeclaredField(fieldName); f.setAccessible(true); f.set(o, value); } public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException { MyClass o = new MyClass(); // 修改任意属性,即使是私有的 changeFieldValue(o, "name", "二当家的白帽子"); // 调用任意方法,即使是私有的 callMethod(o, "printName"); }}class MyClass { // 私有属性,只可以调用set方法修改 private String name; private void printName() { // 私有方法,只有本类自己的实例可以调用 System.out.println("My name is " + name); } public String getName() { return name; } public void setName(String name) { this.name = name; }}
。
是时候揭秘魔法的真面目了,没错,也是利用了反射.
import java.lang.reflect.Field;public class Test { /** * 修改字符串内部的值 * @author 二当家的白帽子 https://le-yi.blog.csdn.net/ * @param str * @param value */ private static void changeStrValue(String str, char[] value) { try { Field f = str.getClass().getDeclaredField("value"); f.setAccessible(true); f.set(str, value); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { changeStrValue("abc", new char[]{"d","e","f"}); // 这里的"abc"字符串和上面调用changeStrValue的参数"abc"会指向同一块内存 String abc = "abc"; System.out.println("abc"); System.out.println(abc); System.out.println("abc".equals(abc)); }}
要理解这段代码,除了反射机制还需要了解java对于字符串的处理。"字符串常量池"已经超出本文的范围,是另一个话题,本文就不多说了.
原本字符串内容是"abc",我们正常情况下无法修改这个内容,因为String是不变类。但是反射大法却可以打破一切禁忌.
。
一般的程序可能用不到写反射的代码。但是像spring这样的框架,如果没有反射,我真的想不出如何实现呢。哪怕永远不需要用反射,了解机制对我们都有着莫大的好处.
本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注我的更多内容! 。
原文链接:https://blog.csdn.net/leyi520/article/details/118676211 。
最后此篇关于java上乘武功入门--反射的文章就讲到这里了,如果你想了解更多关于java上乘武功入门--反射的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在编写一个具有以下签名的 Java 方法。 void Logger(Method method, Object[] args); 如果一个方法(例如 ABC() )调用此方法 Logger,它应该
我是 Java 新手。 我的问题是我的 Java 程序找不到我试图用作的图像文件一个 JButton。 (目前这段代码什么也没做,因为我只是得到了想要的外观第一的)。这是我的主课 代码: packag
好的,今天我在接受采访,我已经编写 Java 代码多年了。采访中说“Java 垃圾收集是一个棘手的问题,我有几个 friend 一直在努力弄清楚。你在这方面做得怎么样?”。她是想骗我吗?还是我的一生都
我的 friend 给了我一个谜语让我解开。它是这样的: There are 100 people. Each one of them, in his turn, does the following
如果我将使用 Java 5 代码的应用程序编译成字节码,生成的 .class 文件是否能够在 Java 1.4 下运行? 如果后者可以工作并且我正在尝试在我的 Java 1.4 应用程序中使用 Jav
有关于why Java doesn't support unsigned types的问题以及一些关于处理无符号类型的问题。我做了一些搜索,似乎 Scala 也不支持无符号数据类型。限制是Java和S
我只是想知道在一个 java 版本中生成的字节码是否可以在其他 java 版本上运行 最佳答案 通常,字节码无需修改即可在 较新 版本的 Java 上运行。它不会在旧版本上运行,除非您使用特殊参数 (
我有一个关于在命令提示符下执行 java 程序的基本问题。 在某些机器上我们需要指定 -cp 。 (类路径)同时执行java程序 (test为java文件名与.class文件存在于同一目录下) jav
我已经阅读 StackOverflow 有一段时间了,现在我才鼓起勇气提出问题。我今年 20 岁,目前在我的家乡(罗马尼亚克卢日-纳波卡)就读 IT 大学。足以介绍:D。 基本上,我有一家提供簿记应用
我有 public JSONObject parseXML(String xml) { JSONObject jsonObject = XML.toJSONObject(xml); r
我已经在 Java 中实现了带有动态类型的简单解释语言。不幸的是我遇到了以下问题。测试时如下代码: def main() { def ks = Map[[1, 2]].keySet()
一直提示输入 1 到 10 的数字 - 结果应将 st、rd、th 和 nd 添加到数字中。编写一个程序,提示用户输入 1 到 10 之间的任意整数,然后以序数形式显示该整数并附加后缀。 public
我有这个 DownloadFile.java 并按预期下载该文件: import java.io.*; import java.net.URL; public class DownloadFile {
我想在 GUI 上添加延迟。我放置了 2 个 for 循环,然后重新绘制了一个标签,但这 2 个 for 循环一个接一个地执行,并且标签被重新绘制到最后一个。 我能做什么? for(int i=0;
我正在对对象 Student 的列表项进行一些测试,但是我更喜欢在 java 类对象中创建硬编码列表,然后从那里提取数据,而不是连接到数据库并在结果集中选择记录。然而,自从我这样做以来已经很长时间了,
我知道对象创建分为三个部分: 声明 实例化 初始化 classA{} classB extends classA{} classA obj = new classB(1,1); 实例化 它必须使用
我有兴趣使用 GPRS 构建车辆跟踪系统。但是,我有一些问题要问以前做过此操作的人: GPRS 是最好的技术吗?人们意识到任何问题吗? 我计划使用 Java/Java EE - 有更好的技术吗? 如果
我可以通过递归方法反转数组,例如:数组={1,2,3,4,5} 数组结果={5,4,3,2,1}但我的结果是相同的数组,我不知道为什么,请帮助我。 public class Recursion { p
有这样的标准方式吗? 包括 Java源代码-测试代码- Ant 或 Maven联合单元持续集成(可能是巡航控制)ClearCase 版本控制工具部署到应用服务器 最后我希望有一个自动构建和集成环境。
我什至不知道这是否可能,我非常怀疑它是否可能,但如果可以,您能告诉我怎么做吗?我只是想知道如何从打印机打印一些文本。 有什么想法吗? 最佳答案 这里有更简单的事情。 import javax.swin
我是一名优秀的程序员,十分优秀!