精华内容
下载资源
问答
  • 利用java反射原理调用方法时,常先需要传入方法参数数组才能取得方法。该方法参数数组采用动态取得的方式比较合适
  • 反射方法 的简单使用

    千次阅读 多人点赞 2020-06-07 19:26:41
    反射方法 的简单使用 文章目录反射方法 的简单使用获得字节码文件对象的三种方式用字节码文件对象来构建一个类的对象构造方法对象方法对象得到属性对象 获得字节码文件对象的三种方式 Object类的getClass方法 ...

    反射方法 的简单使用

    获得字节码文件对象的三种方式

    首先第一句,一切皆对象。类、属性、方法、构造器都是对象

    该篇文章其实就注重两个点、是否有declared前缀,带有private的记得调用setAccessible
    所涉及到的类:Class、Field、Construcotr、Method

    1. Object类的getClass方法

    2. 类型.class 属性

    3. Class.forName(“类的路径”)

      image-20200607161433834

    都为true,内存地址是一样的。在程序的运行中,Person的class文件只被加载了一次。
    注意:除了反射案例。在此赠送一套最新Java架构项目实战教程+大厂面试题库,想学的 点击此处免费获取,小白勿进哦

    image-20200607161626586

    也为true,可知只加载了一次

    image-20200607161907591

    也为true

    用字节码文件对象来构建一个类的对象

    image-20200607162932098

    字节码文件对象中包含:

    那么 这4个字节码文件对象中叫什么呢?

    java文件字节码文件
    字节码文件对象
    构造方法构造方法对象(类型Constructor)
    成员变量成员变量对象(类型Field)
    成员方法成员方法(类型Method)

    之前一直用new的形式来创建一个类的对象

    Person p = new Person()

    加粗部分是类的构造方法,因为对象是通过构造方法创建的

    用字节码文件中的构造器对象来创建一个类的对象——Constructor对象

    image-20200607165151665

    获得Constructor来创建对象

    注意:getDeclaredConstructor(Class<?>… parameterTypes)
    这个方法会返回指定参数类型的所有构造器,**包括public的和非public的,**当然也包括private的。
    getDeclaredConstructors()的返回结果就没有参数类型的过滤了。

    再来看getConstructor(Class<?>… parameterTypes)
    这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。
    getConstructors()的返回结果同样也没有参数类型的过滤。

    用反射有什么好处呢?之前Spring ioc有讲。可以通过配置文件动态创建对象:

    来:

    创建一个a.txt用来存储要创建对象的 全路径名称,之后读取这个字符串,用class.forName创建就可以了。以Person为例

    image-20200607165644004

    获取名称后也可创建对象。

    构造方法对象

    四个访问修饰符:

    image-20200607171458965

    image-20200607174759323

    getConstrustors是获取公有的,所以只有一个

    image-20200607174902268

    getDeclaredConstructors这个就是得到所有的

    获取指定的构造器

    image-20200607175158291

    这是public的,如果不是public,使用getConstructor获得指定方法机会报NoSuchMethodException

    image-20200607175310534

    所以也是用带Declared的getDeclaredConstructor

    那么其他访问修饰符呢?

    image-20200607180232347

    私有的可以得到构造器,但是不能创建对象

    image-20200607180338222

    通过constructor.setAccessible(true)设置为可以访问

    方法对象

    它也有这些

    image-20200607180610378

    image-20200607180641434

    其他方法是因为还有Object的,当然这是public的,要所有的需要加上Declared

    先给Person加上getter与setter,以及该类的一个私有方法

    image-20200607181104007

    image-20200607181124194

    可以发现有以下的区别

    1.不带declared是得到所有的public修饰的method 包括从父类继承过来的Declared

    2.带declared是得到当前类中的所有Method

    image-20200607183830023

    注意,getMethod()是得到公有的方法,同样的也有getDeclaredMethod()

    同样的,如果将getName()这个方法的访问权限改为私有的,那么也将报 **IllegalAccessException **

    image-20200607184211889

    那么也是一样的,需要设置一下

    image-20200607184320224

    得到属性对象

    getField跟getDeclaredField,跟上面的一样的。因为这里是private

    image-20200607190400689

    展开全文
  • 主要介绍了Java使用反射调用方法,结合实例形式分析了java使用反射调用对象方法的相关操作技巧,需要的朋友可以参考下
  • Java 反射创建get set方法及反射方法的调用
  • java 中通过反射创建对象

    Java 的反射

    涉及到的知识:1.通过反射创建对象;2.通过反射调用某个类的方法。

    这篇主要是讲解 通过反射创建对象


    一、反射的简单定义:java可以在运行时动态获取某个类的类信息,这就是java的反射。

    1. 涉及Class(类)
    Class 类的实例表示正在运行的 Java 应用程序中的类和接口
    Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的。

    这个类指的是类对象,是具体某个类对象,描述类信息。不是我们平时说的对象,这样说有点抽象,举个例子:

    比如:String a=new String ();这个a 是String 的对象,不是类对象;

    Class c=String.class;这个c就是String的类对象,描述的是String这个class类的信息

    那么怎么样才能得到某个类的类对象呢?

    1.得到相应的 类对象

    class 里面有个方法 Class c= Class.forName(className),通过这个方法可以得到相应的  类信息
    
    Class.forName(className) 返回与带有给定字符串名的类或接口相关联的 Class 对象,其中className是字符串,----要求:所需类的完全限定名。比如String的className 为 java.lang.String   ,如果是自定义的对象,也需要传入完整的路径  例如:![这是一个类的包名](//img-blog.csdn.net/20180510102221797?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0dSWV9ZSg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) ,有个Student的类,则className 为 com.paynews.javalib.Student
    
    调运改方法会抛出异常:
    LinkageError - 如果链接失败
    ExceptionInInitializerError - 如果此方法所激发的初始化失败
    ClassNotFoundException - 如果无法定位该类

    2.通过类对象得到 所表示的类的实例

    2.1创建不带任何参数的对象(构造函数没有参数列表)

    得到了类对象,创建它表示的类的一个新的实力,调用 public T newInstance();
    
    public T newInstance();
    
        创建此 Class 对象所表示的类的一个新实例。如同用一个带有一个空参数列表的 new 表达式实例化该类。如果该类尚未初始化,则初始化这个类。
        注意,此方法传播 null 构造方法所抛出的任何异常,包括已检查的异常。使用此方法可以有效地绕过编译时的异常检查,而在其他情况下编译器都会执行该检查。 Constructor.newInstance 方法将该构造方法所抛出的任何异常包装在一个(已检查的)InvocationTargetException 中,从而避免了这一问题。
    
    返回:
       **此对象所表示的类的一个新分配的实例。**
    抛出:
       IllegalAccessException - 如果该类或其 null 构造方法是不可访问的。
       InstantiationException - 如果此 Class 表示一个抽象类、接口、数组类、基本类型或 void; 或者该类没有 null 构造方法; 或者由于其他某种原因导致实例化失败。
       ExceptionInInitializerError - 如果该方法引发的初始化失败。
       SecurityException - 如果存在安全管理器 s,并满足下列任一条件:
       调用 s.checkMemberAccess(this, Member.PUBLIC) 拒绝创建该类的新实例
    调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对 s.checkPackageAccess() 的调用拒绝访问该类的包
    
    注:这个方法是 Class类中的方法,且只能创建不带任何参数的对象形式(构造函数没有参数列表)。直接返回T模版类型的对象,自己要把它转换为实际类型。
    
    举例:
    Class c=Class.forName("java.lang.String");
    String s=(String)c.newInstance();

    2.2创建带参数的对象

    创建带参数的对象(构造函数中有参数)比较复杂,因为构造函数里面的参数可以是不同的,所以创建实例的时候,需要指明函数中的参数列表,传入相应的参数形式,否则会抛出异常。
    
    调用的方法:
    public Constructor<T> getConstructor(Class<?>... parameterTypes) 
    
    返回一个 Constructor 对象,它反应此 Class类对象 所表示的 类 的公共构造方法,parameterTypes 参数是Class类对象的数组,对应构造函数中的参数,这个数组的顺序 与 构造函数中参数顺序一致。这样理解比较抽象,举个例子:
    public Student getStudent(String name ,int age,String content){}parameterTypes对应的Class 类对象的数组
     Class name=Class.forName("java.lang.String");
     Class age=Interger.TYPE;
     Class content=Class.forName("java.lang.String"); 
    
     parameterTypes[0]=name
     parameterTypes[1]=age
     parameterTypes[2]=content
     像这样一样要一一对应
    
    参数:
       parameterTypes - 参数数组
    返回:
       与 指定的 parameterTypes(Class对象数组) 相匹配的 公共构造方法的 Constructor 对象
    抛出:
       NoSuchMethodException - 如果找不到匹配的方法。
       SecurityException - 如果存在安全管理器 s,并满足下列任一条件:
    调用 s.checkMemberAccess(this, Member.PUBLIC) 拒绝访问构造方法
    调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对 s.checkPackageAccess() 的调用拒绝访问该类的包

    需要注意的是:

    如果是基本类型请使用它们的Type字段,如果是非基本类型使用class字段来返回其CLass类信息。


    得到构造方法的 Constructor 对象,下一步就是得到相应 类 的实例了。

    public T newInstance(Object... initargs)  
    
    使用 此Constructor对象的构造方法 来 创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。个别参数会自动解包,以匹配基本形参,必要时,基本参数和引用参数都要进行方法调用转换。
    如果底层构造方法所需形参数为 0,则所提供的 initargs 数组的长度可能为 0 或 null。
    
    如果构造方法的声明类是非静态上下文的内部类,则构造方法的第一个参数需要是封闭实例;请参阅Java 语言规范 第 15.9.3 节。
    
    如果所需的访问检查和参数检查获得成功并且实例化继续进行,这时构造方法的声明类尚未初始化,则初始化这个类。
    如果构造方法正常完成,则返回新创建且已初始化的实例。
    
    参数:
       initargs - 将作为变量传递给构造方法调用的对象数组;基本类型的值被包装在适当类型的包装器对象(如 Float 中的 float)中。(之前parameterTypes参数对应的Class对象数组,initargs则是Class对象数组中代表的类的具体的数值)
    
    返回:
       通过调用此对象表示的构造方法来创建的新对象
    
    抛出:
       IllegalAccessException - 如果此 Constructor 对象实施 Java 语言访问控制并且底层构造方法是不可访问的。
       IllegalArgumentException - 如果实参和形参的数量不同;如果基本参数的解包转换失败;如果在可能的解包后,无法通过方法调用转换将参数值转换为相应的形参类型;如果此构造方法属于枚举类型。
    InstantiationException - 如果声明底层构造方法的类表示抽象类。
    InvocationTargetException - 如果底层构造方法抛出异常。
    ExceptionInInitializerError - 如果此方法引发的初始化失败。

    以下是以上总结的一个实例

    1.自定义一个类(作为 非基本类型的 类)

    public class CustomClass {
    
        private String name = "";
    
        CustomClass(String name) {
            this.name = name;
            show();//如果创建成功,进行展示显示
        }
    
        public void show() {
            System.out.println(name);
        }
    
        @Override
        public String toString() {
            return "CustomClass=" + name;
        }
    }

    2.创建 反射类(里面有 不带参数的构造函数 和 代参的构造函数(参数有 整型、字符串、自定义类))

    class ReflectClass {
        private String name = "ReflectClass";
    
        public ReflectClass(int age, String name, CustomClass my) {
            this.name = name;
            show(age, name, my);//创建成功后展示
        }
    
        public ReflectClass() {//构造函数重载,使用不同的参数列表创建对象
            //没有带参数的构造方法
        }
    
        public final void show(int age, String name, CustomClass my) {
            System.out.println("age=" + age + " name=" + name + " my=" + my);
        }
    
        @Override
        public String toString() {
            return "ReflectClass=" + name;
        }
    }

    3.展示

    public class HomeClass {
    
        public static void main(String args[]) {
            //创建不带参数的对象
            ReflectClass rc1=(ReflectClass) HomeClass.getInstance("com.jijing.classDemo.ReflectClass");
            System.out.println("ReflectClass111="+rc1);
    
            System.out.println("******************************");
            //创建 带参数的 对象
            ReflectClass rc2 = (ReflectClass) HomeClass.getInstance("com.paynews.javalib.ReflectClass",
                    new Class[]{Integer.TYPE, String.class, CustomClass.class},
                    new Object[]{20, "这是String的值", new CustomClass("这是自定义类")});
    
            System.out.println("需要反射的 ReflectClass =" + rc2);
        }
    
        /**
         * @param name 需实例化类 的全路径
         * @return 不带参数的反射创建对象
         */
        public static Object getInstance(String name){
            Class c=getClass(name);
            Object o=null;
            try {
                o=c.newInstance();
            } catch (InstantiationException ex) {
                Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
            }
            return o;
        }
    
        /**
         * @param className 需实例化类 的全路径
         * @return 返回根据className指明的类信息
         */
        public static Class getClass(String className){
            Class c=null;
            try {
                c=Class.forName(className);
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
            }
            return c;
        }
    
        /**
         * @param name  需要返回的类 的全路径
         * @param classParas  Class类对象数组
         * @param paras   对应的具体的数值数值
         * @return 返回参数的类的实力
         */
        public static Object getInstance(String name,Class classParas[],Object paras[]){
            Object o=null;
            try {
                Class c=getClass(name);
                Constructor con=c.getConstructor(classParas);//获取使用当前构造方法来创建对象的Constructor对象,用它来获取构造函数的一些
                try {
                    //信息
                    o=con.newInstance(paras);//传入当前构造函数要的参数列表
                } catch (InstantiationException ex) {
                    Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalAccessException ex) {
                    Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
                } catch (IllegalArgumentException ex) {
                    Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException ex) {
                    Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
                }
            } catch (NoSuchMethodException ex) {
                Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
            } catch (SecurityException ex) {
                Logger.getLogger(ClassMain.class.getName()).log(Level.SEVERE, null, ex);
            }
    
            return o;//返回这个用Object引用的对象
        }
    }

    参考资料:直到完成无形的天空 的Java通过反射创建对象

    展开全文
  • 在调用反射方法之后,@Autowired注入对象为空。 解决方法: method.invoke(object, parameters) 改成  method.invoke(spring.getBean("beanName"), parameters) 这样这个问题就解决了。 获取...

    在调用反射方法之后,@Autowired注入对象为空。

    解决方法:

    method.invoke(object, parameters)

    改成 

    method.invoke(spring.getBean("beanName"), parameters)

    这样这个问题就解决了。

    获取spring上下文的方法: https://www.cnblogs.com/yjbjingcha/p/6752265.html

    展开全文
  • 反射机制常用方法总结

    千次阅读 2018-09-29 23:06:10
    所谓反射,就是给你一个XX.class文件,你通过反射方法,能够拿到该XX类相关的所有资源,比如该类所在位置,通过该类创建一个对象x,获取这个类X创建的对象x的所有公有、私有属性和公有、私有方法。这个技术你值得...

    反射,是在java中非常有用,在框架中也经常接触的一种方法,所以反射是在开发中必须会的东西
    所谓反射,就是给你一个XX.class文件,你通过反射方法,能够拿到该XX类相关的所有资源,比如该类所在位置,通过该类创建一个对象x,获取这个类X创建的对象x的所有公有、私有属性和公有、私有方法。这个技术你值得学习。
    首先,我写了一个TestClass.java文件,作为编译成class后要使用的TestClass.class文件,然后ReflectDemo.java演示所有反射技术的demo,这里你将学会反射里常见的方法。先给大家一个方法总结,然后看代码,熟悉相关应用。

    1、方法总结:
    1.1获取class的三种方法:
    第一种:Class clazz = Class.forName(XX.class的全包名)
    第二种:Class clazz = XX xx = new XX();xx.getClass();
    第三种:Class clazz = XX.class;
    见实例代码test0()
    1.2如何通过类class文件,拿到该文件里面的资源?这种方式获取的路径方法,永远是固定的,不会随着工程的路径改变而改变,始终都能获取到。
    比如,TestClass.class文件(被编译后)所在的classes文件夹下,有prop.properties属性文件,如何拿到这个文件的绝对路径?如何把该文件加载到流中?通过在clazz中有个getClassLoader()方法,得到类加载器ClassLoader,然后再通过getSource()的方法,得到URL,然后再getPath()得到路径名
    两种固定写法:
    第一种:
    Class clazz = TestClass.class;
    ClassLoader classLoader = clazz.getClassLoader();
    URL url = classLoader.getResource("prop.properties");
    String path = url.getPath();
    InputStream ins = new FileInputStream(path);
    链式写法为:String path = TestClass.class.getClassLoader().getResource("prop.properties").getPath();
    InputStream ins = new FileInputStream(path);
    第二种[直接将资源加载成流]:InputStream ins = TestClass.class.getClassLoader().getSourceAsStream("prop.properties");
    见实例代码test()
    1.3如何用该class文件,创建一个对象?
    创建对象有两种方法,直接用xx.newInstance()或使用xx.constructor()获取构造器然后再newInstance()。
    第一种:
    Class xx = TestClass.class;
    Object obj = xx.newInstance();//无参构造方法
    TestClass tc = (TestClass)obj;//转换为该类的对象
    第二种:
    Class xx = TestClass.class;
    Constructor cst = xx.getConstructor();//无参构造方法
    Object obj = cst.newInstance();//这个也不能有参数
    TestClass tc = (TestClass)obj;//转换为该类的对象
    见实例代码test1()、test2()
    注意:这两种方法,只能使用无参的构造方法来创建无参默认的对象,如果想创建带参的对象呢?
    使用构造器,然后指定参数类型,再创建实例对象时,将实参数传递
    Class xx = TestClass.class;
    Constructor cst = xx.getConstructor(String.class,int.class);//指定参数类型的带参构造方法
    Object obj = cst.newInstance("李四",18);//顺便指定好实参
    TestClass tc = (TestClass)obj;//转换为该类的对象
    见实例代码test2()

     

    getDeclaredConstructor()与getConstructor的区别
    首先看getDeclaredConstructor(Class<?>... parameterTypes) 
    这个方法会返回制定参数类型的所有构造器,包括public的和非public的,当然也包括private的。
    getDeclaredConstructors()的返回结果就没有参数类型的过滤了。


    再来看getConstructor(Class<?>... parameterTypes)
    这个方法返回的是上面那个方法返回结果的子集,只返回制定参数类型访问权限是public的构造器。
    getConstructors()的返回结果同样也没有参数类型的过滤。

    getMethods()和:getDeclaredMethods()的区别

    1:getMethods(),该方法是获取本类以及父类或者父接口中所有的公共方法(public修饰符修饰的)

    2:getDeclaredMethods(),该方法是获取本类中仅自己定义的所有方法,包括私有的(private、protected、默认以及public)的方法。

    getMethods(),getDeclaredMethods()获取的方法是无序的,fileds相应的获取方法也一样
    注意:获得公有私有的属性和方法时,必须指定获取哪个对象的,必须创建好一个对象。

    getFileds()和getDeclaredMehods()的区别类似

    1.4如何获取到该类创建的对象中的公有及私有属性值呢?需要用到xx.getField().get()或xx.getDeclaredField().setAccessible().get();
    注意:获得公有私有的属性和方法时,必须指定获取哪个对象的,必须创建好一个对象。
    Class xx = TestClass.class;
    Constructor cst = xx.getConstructor(String.class,int.class);//指定参数类型的带参构造方法
    Object obj = cst.newInstance("李四",18);//顺便指定好实参
    TestClass tc = (TestClass)obj;//转换为该类的对象
    //获取公有属性name:
    Field fieldName = xx.getField("name");//指定哪个字段
    Object name = fieldName.get(tc);//获取tc对象的name值
    String strname = (String)name;
    //获取私有属性age:
    Field fieldAge = xx.getDeclaredField("age");//获取所有声明的一个叫age的字段
    fieldAge.setAccessible(true);//使得该私有age可以被获取
    Object age = fieldAge.get(tc)//获取tc的私有age
    int intage = (int)age;
    见实例代码test3()
    1.5如何获取到该类创建的对象中的公有及私有的方法呢?xx.getMethod().invoke()或者xx.getDeclaredMethod().setAccessible().invoke();
    Class xx = TestClass.class;
    Constructor cst = xx.getConstructor();//无参构造方法
    Object obj = cst.newInstance();//这个也不能有参数
    TestClass tc = (TestClass)obj;//转换为该类的对象
    //获得公有的无参的方法:
    Method mt1 = xx.getMethod("showPublic");//指定获取哪个方法(showPublic()方法)
    mt1.invoke(tc);//获取对象tc中的showPublic()方法
    //获得公有的带参的方法:
    Method mt2 = xx.getMethod("showPublicParams", String.class,int.class);//指定获取哪个方法,并指定带哪种参数(showPublicParams(String,int)方法)
    mt2.invoke(tc1, "刘二麻子",23);//获取对象tc中的showPublicParams并指定传进两个实参
    //获得私有的无参方法【两步:1.获得声明的方法;2.让该方法可视化】
    Method mt3 = xx.getDeclaredMethod("showPrivate");//获取哪个私有方法(showPrivate()方法)
    mt3.setAccessible(true);//该方法可被获取,即可视化
    mt3.invoke(tc);//获取对象tc中的showPrivate()方法
    见实例代码test4()
    1.6如果一个方法中的参数带了泛型,怎么获取该参数以及泛型参数的类型?如参数为(List,int)
    见实例代码test5()。其中,getGenericParameterTypes只能获取方法的参数列表中的类型,返回的是一个类型数组[list类型,int类型];ParameterizedType是Type的子接口,需要向下转型为ParameterizedType,然后再使用方法getActualTypeArguments获取泛型的参数类型,返回的是个类型数组[People类型,String类型]。
    见实例代码test5()
    2、实例代码:
    TestClass.java的代码【有公有私有属性,有公有私有方法,有带返回值的方法,有带泛型的方法】如下:
    package com.dou.reflect;

    import java.util.List;

    public class TestClass {
        public String name = "张三";//公有属性
        private int age = 28;//私有属性

        public TestClass() {//带参构造
            super();
            // TODO Auto-generated constructor stub
        }

        public TestClass(String name, int age) {//满参构造
            super();
            this.name = name;
            this.age = age;
        }

        public void showPublic() {//无参共有方法
            System.out.println("这是无参共有方法showPublic()->" + this.name + ":" + this.age);
        }
        public void showPublicParams(String name, int age) {//带参公有方法
            System.out.println("这是带参共有方法showPublicParams(String,int)->" + name + ":" + age);
        }
        public String showHello(){//带返回值公有无参方法
            return "hello word";
        }
        public void showParameterized(List list,int num){//带泛型公有方法
            for (String str : list) {
                System.out.println(str+num);
            }
        }
        
        private void showPrivate() {//无参私有方法
            System.out.println("这是无参私有有方法showPrivate()->" + this.name + ":" + this.age);
        }
    }
    //--------------
    ReflectDemo.java的代码【常用反射方法】如下:
    package com.dou.reflect;

    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.ParameterizedType;
    import java.lang.reflect.Type;
    import java.util.List;

    import org.junit.Test;

    public class ReflectDemo2 {
        
        @Test
        //获得带返回值的方法,以及参数类型和参数化的类型。如List的TestClass类型
        public void test5() throws Exception {
            Class clazz1 = TestClass.class;
            TestClass tc1 = (TestClass)clazz1.newInstance();
            Method m1 = clazz1.getMethod("showHello");
            String str = (String) m1.invoke(tc1);
            System.out.println(str);
            
            //参数类型showParameterized(List list,int num)
            Method m2 = clazz1.getMethod("showParameterized", List.class,int.class);
            //获得你这个method对象(某个方法)的参数列表
            Type[] types = m2.getGenericParameterTypes();
            for (Type type : types) {
                System.out.println(type.toString());
                //java.util.List
                //int
            }
            
            //获得泛型的类型,ParameterizedType是Type的子接口,代表参数化类型
            Type tp = m2.getGenericParameterTypes()[0];//参数列表中的第一个参数
            ParameterizedType ptp = (ParameterizedType)tp;
            //getActualTypeArguments获得泛型参数列表里的泛型的类型
            Type T_type = ptp.getActualTypeArguments()[0];//泛型里的第一个参数列表
            System.out.println(T_type.toString());//class java.lang.String
        }
        
        @Test
        //通过反射方法,获取类创建的对象中获取公有和私有方法
        public void test4() throws Exception {
            //showPublic/showPublicParams/showPrivate
            Class clazz1 = TestClass.class;
            TestClass tc1 = (TestClass)clazz1.newInstance();//创建一个被获取的对象
            //获得公有的无参的方法
            Method mt1 = clazz1.getMethod("showPublic");
            mt1.invoke(tc1);
            //获得公有的带参的方法
            Method mt2 = clazz1.getMethod("showPublicParams", String.class,int.class);
            mt2.invoke(tc1, "刘二麻子",23);
            
            //获得私有的无参方法【两步:1.获得声明的方法;2.让该方法可视化】
            Method mt3 = clazz1.getDeclaredMethod("showPrivate");//获取私有方法
            mt3.setAccessible(true);//该方法可视化
            mt3.invoke(tc1);
        }
        
        @Test
        //通过反射方法,获取类中的公有属性和私有属性
        public void test3() throws Exception {
            Class clazz1 = TestClass.class;
            //获取公有属性[需要一个获取哪个对象的实际对象]
            Field f1 = clazz1.getField("name");
            TestClass tc1 = (TestClass)clazz1.newInstance();
            Object name1 = f1.get(tc1);
            System.out.println("默认构造函数对象的公有属性name值:"+name1);
            
            //想用带参的,则需要用constructor方法指定参数
            Constructor cs1 = clazz1.getConstructor(String.class,int.class);
            TestClass tc2 = (TestClass)cs1.newInstance("李四",18);
            Field fl2 = clazz1.getField("name");
            Object name2 = fl2.get(tc2);
            System.out.println("带参构造函数对象的公有属性name值:"+name2);
            
            //想获取私有的属性age【两步:1.获取私有属性方法getDeclaredField();2.将私有属性可视化setAccessible();】
            Field fl3 = clazz1.getDeclaredField("age");//获取私有属性的特有方法
            fl3.setAccessible(true);//将私有属性公开可视化的方法
            Object age = fl3.get(tc2);
            System.out.println("私有属性age的值:"+age);
        }

        @Test
        //根据类文件,通过构造器getConstructor()创建对象,可以调用带参的构造方法创建带参的对象
        public void test2() throws Exception {
            Class clazz1 = TestClass.class;
            //默认无参的构造方法创建对象
            Constructor cc = clazz1.getConstructor();
            TestClass tc1 = (TestClass)cc.newInstance();
            tc1.showPublic();
            //想调用有参的构造方法,创建带参的对象
            Constructor cc2 = clazz1.getConstructor(String.class,int.class);
            TestClass tc2 = (TestClass)cc2.newInstance("李四",18);
            tc2.showPublic();
        }
        
        @Test
        //通过类的类对象.newInstance()创建一个对应的无参对象
        public void test1() throws Exception{
            Class clazz1 = Class.forName("com.dou.reflect.TestClass");
            Object obj = clazz1.newInstance();
            TestClass tc = (TestClass)obj;
            tc.showPublic();
        }
        
            @Test
        public void test0() throws Exception{
            //活动Class对象的三种方法
            //getClassLoader()只能获取工程编译后的classes文件夹下的所有资源,而对应的工程路径就是src下的路径
            //所有放配置文件放在src下,通过类加载器来获取当前工程下的资源,是最常用的方法
            //Class.forName(类的全包名)
            Class clazz1 = Class.forName("com.dou.reflect.ReflectDemo1");
            ClassLoader classLoader = clazz1.getClassLoader();
            URL resource = classLoader.getResource("prop.properties");
            String path = resource.getPath();
            System.out.println(path);
            
            //2.类.class()
            Class clazz2 = ReflectDemo1.class;
            ClassLoader cl = clazz2.getClassLoader();
            InputStream in = cl.getResourceAsStream("prop.properties");
            Properties prop = new Properties();
            prop.load(in);
            System.out.println("prop.properties加载完成");
            Set

    keys = prop.keySet();
            for (Object object : keys) {
                String value = prop.getProperty((String)object);
                System.out.println(object+"="+value);
            }
            
            //3.对象.getClass()
            TestClass ts = new TestClass();
            ts.showPublic();
            Class clazz3 = ts.getClass();
            ClassLoader csl = clazz3.getClassLoader();
            URL url = csl.getResource("prop.properties");
            String path2 = url.getPath();
            System.out.println("prop.properties的全路径:"+path2);
        }
        
        @Test
        public void test() throws Exception{
            //获取src、classes路径下的资源全路径,并加载到文件流中
            //传统两步
            String path = ReflectDemo1.class.getClassLoader().getResource("prop.properties").getPath();
            InputStream is = new FileInputStream(path);
            System.out.println("prop.properties文件完成加载1");
            
            //一步走
            InputStream ins = ReflectDemo1.class.getClassLoader().getResourceAsStream("prop.properties");
            System.out.println("prop.properties文件完成加载2");
        }

    }
     

    反射总结
    反射四大核心类:Class、Constructor、Method、 Filed
    
    一、Class类:
    
    1.核心操作:Object
        public final native Class<?> getClass();
        返回值:Class类
        Class:反射核心类,描述其他类的结构
    
    2.Class类的三种实例化方式(每一个类的Class的对象有且只有一个,由JVM加载时创建对象)
        a.任意对象.getClass()
        b.类名.class
        c.调用Class的静态方法:Class.forNmae(String className);
    
    3.利用Class对象反射创建类的对象:
        Class类中提供如下方法:
            publci T newInstance() thorows 抛出异常
    
    二、Constructor类:
    
    1.Class提供的newInstance()默认调用类中【无参构造】
    
    2.取得类中构造方法
     public Constructor<T> getConstructor(Class<?> ... parameterTypes)
    
    3.取得类中所有构造
    public Constructor<?>[] getConstructors() throws Execption
    
    注意:2和3只能取得修饰符为public的构造方法
    
    4.取得类中所有构造方法与修饰符无关
        public Constructor<T> getDeclaredConstructor()
    
        public Constructor<?>[] getDeclaredConstructors()
    
        // 破坏封装
        setAccessible(boolean);
    
    三、Method类:
    
    1.取得所有普通方法
        Method[] getMethods() throws SecurityException
        返回本类及父类的所有public普通方法
    
        getDeclaredMethods()
        返回本类所有普通方法,与修饰符无关
    
    2.取得指定方法
        public Method getMethod(方法名,方法参数)
        返回【本类及父类】的所有public普通方法
    
        public Method getDeclaredMethod(方法名,方法参数)
        返回【本类】所有普通方法,与修饰符无关
    
    3.调用
        Method提供的
        public Object invoke(类的实例化对象,方法具体参数)
    
    例子:
    public static void main(String[] args) throws Exception{
            // 取得Class对象
            Class<?> cls = People.class;
    
            // 取得有参构造
            Constructor<?> constructor = cls.getDeclaredConstructor(String.class);
    
            // 创建实例化对象
            People people = (People) constructor.newInstance("Leon");
    
            // 取得指定方法名称的的方法
            Method method = cls.getMethod("setAge", Integer.class);
    
            // 调用方法
            method.invoke(people, 18);
            System.out.println(people);
        }
    
    四、Filed类:(反射调用类中属性)与Method类似
    
    1.取得所有类中属性
        Filed[] getFileds() throws SecurityException
        Filed[] getDeclaredFileds() 
    
    2.取得类中指定属性
        getFiled()
        getDeclaredFiled()
    
    3.属性调用:   
        设置属性内容:
            public void set(Object 类的实例化对象:obj,Object 属性值:value);
        取得属性内容:
            public Object get(Object obj)
    
        getType()// 取得属性类型
    
    

    转载自:https://blog.csdn.net/it666dhw/article/details/78654557

    ---------------------
    https://blog.csdn.net/qq_39026129/article/details/81565520?utm_source=copy 

    展开全文
  • C# 反射 方法 带参数是(委托型) 方法 (委托 ) { 委托1= 委托 }
  • 上一篇讲了 通过反射创建对象,这一篇说说 通过反射调用一个类的方法 如果看过了上一篇文章,那么这一篇就很好理解了 如同上一篇文章一样,主要的方法基本上都是通过 Class 这个类(是个入口) 1.得到方法 对象...
  • java反射改变方法的返回值

    千次阅读 2021-02-12 23:13:47
    import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;/*** @author lijinnan* @date:2014-5-26*/public class ChangeReturnValue {/...
  • 反射得到方法返回值

    千次阅读 2019-04-15 10:06:31
    PropertyDescriptor pd; Method getMethod; pd = new PropertyDescriptor(para, pojo); getMethod = pd.getReadMethod();//获得get方法 if (pd != null) { Object o = getMethod....//执行get方法返回一个Object ...
  • C#反射方法:程序集反射、类型反射、接口反射、类型成员反射   反射(原创推荐)  在程序中,当我们需要动态的去加载程序集的时候(将对程序集的引用由编译时推移到运行时),反射是一种很好的选择。反射为...
  • Java反射(常用方法详解)

    千次阅读 2019-08-27 17:08:20
    对于运行阶段的一个对象,也可以动态的获取这个对象的属性、方法、构造方法等信息的机制,称之为反射机制。反射机制是java中非常重要的一个技术。它是JDK1.5的新特性使用反射,需要先获取一个类或者对象的字...
  • java 反射获取方法属性和方法调用

    千次阅读 2019-05-08 21:04:14
    这种动态获取信息,以及动态调用对象方法的功能叫java语言的反射机制;(通俗点讲, 通过反射,该类对我们来说是完全透明的,想要获取任何东西都可以(转载);) 下面我就通过反射获取类中的方法: 先创建一个...
  • 一.Java反射拿到调用对象的方法 1.通过Class.forName(“包名+方法的类名”)拿到方法的对象; 如:Class&lt;?&gt; clazz = Class.forName("ReflectionTest");  也可以通过实例,获取方法的对象...
  • 反射系列之Method方法反射

    千次阅读 2018-03-30 17:23:04
    * 调用反射类中的方法 */ public static void main(String[] args) { try { String attrbute = "name" ; //属性名称 Class<?> cls = Class. forName (Preson. class .getName()); Object obj = cls...
  • 本例演示了如何使用反射,调用类的静态方法,封装了工具类ClsTool,统一实现静态方法的调用。使用反射,在特定场景下,能够很好的简化代码。例如mybatis
  • java 通过反射怎么获取方法中参数值

    千次阅读 2021-02-12 14:02:05
    public T invokeMethod(String beanName, String methodName,Class>[] paramTypes, Object... parameters) {try{Object bean=ApplicationContextHolder.getBean(beanName);Class extends Object>...
  • 绍Java反射获取私有构造函数、属性、方法
  • 反射获取变量:ReflectTool.getSubField(, , ); // 通过反射,获取View的在res/Layout布局中声明的onClick属性名称 // <Button android:id="@+id/button1" android:onClick="OpenLog" /> Button view = ...
  • 利用反射 调用以生成的DLL里的方法. 一个简单的实例清楚现实反射DLL
  • 要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。 getMethods() getMethods(String name,Class<?> …parameterTypes) getDeclaredMethods() ...
  • java8反射获取方法的参数名称 文章目录java8反射获取方法的参数名称1.简要说明2.java类获取方法参数名称测试代码解决方法执行结果3.接口测试代码执行结果解决方法感谢 1.简要说明 演示springboot版本为2.0.3....
  • java 方法反射调用

    千次阅读 2019-03-12 11:12:00
    // setName()是方法名称,但是这个方法名称是根据给定的属性信息拼凑得来的,同时该方法需要接收一个String型的参数 Method setMethod = cls.getMethod("set" + initcap(attribute), String.class) ; // 随后需要...
  • Java反射调用方法

    2014-11-13 15:47:38
    通过Java反射调用方法,适合初级自学者,通俗易懂
  • 主要介绍了C#中方法的直接调用、反射调用与Lambda表达式调用对比,本文着重讲解了方法的三种调用方法以及它们的性能对比,需要的朋友可以参考下
  • Java反射调用带接口类型参数的方法

    千次阅读 2019-08-15 20:47:23
    Java 中反射属于java高阶编程的一大法宝,无论是动态代理还是... 言归正传,近日在用反射调用第三方sdk中一个方法时候,发现了这个方法中带有接口类型的参数,一时不知如何传递接口参数,具体看下面的一个demo方法...
  • Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法反射非常强大,JDBC...
  • Java-反射以及反射调用类中方法

    千次阅读 2018-12-02 18:15:12
    认识反射 反射是对象的反射处理操作。 先来看看“正”操作。 在默认情况下,必须要先导入一个包,而后才能产生类的实例化对象。 如下就是一个正操作。 import java.util.Date;//导入的包 public class Test{...
  • 反射获取方法返回结果

    千次阅读 2018-12-03 10:31:23
    本人微信 zf363133213 欢迎...通过反射获得方法返回结果(抛异常我就省略了) //bean:接口;methodName:方法名;params:参数集合;paramClass:参数的Class;result:方法返回值 public static Object executeReflectMe...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 517,722
精华内容 207,088
关键字:

反射方法

友情链接: 1.zip