gpt4 book ai didi

java上乘武功入门--反射

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 35 4
gpt4 key购买 nike

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));    }}

java上乘武功入门--反射

二当家的第一次看到这个执行结果觉得很有意思。明明应该是"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<>());    }}

java上乘武功入门--反射

  。

了解任意一个类的成员变量和方法

我们一般要使用一个类,先要知道有什么方法和属性,先了解,后使用。但是像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;    }}

java上乘武功入门--反射

  。

调用任意一个对象的属性和方法

像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;    }}

java上乘武功入门--反射

  。

魔法揭秘

是时候揭秘魔法的真面目了,没错,也是利用了反射.

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的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com