美文网首页
java反射——基础语法学习

java反射——基础语法学习

作者: 笑对浮华 | 来源:发表于2021-06-24 17:59 被阅读0次

    写在前面:

    反射技术在框架开发中举足轻重,可以说是框架设计的灵魂,现在市面上绝大部分的框架都用到了反射机制,其在程序的运行过程中,动态操作对象,解耦程序,提高程序扩展性,使得反射机制成为框架设计领域的神器,反射机制也是java进阶必不可少的知识。

    下面是对java反射基础语法的学习和使用:

    一、获取对象类型:

    val name = "aaa"
    val clazz = name.javaClass
    print(clazz)
    

    上面代码定义了一个字符串name,通过调用javaClass获取它的类型(java中调用getClass()方法),运行结果如下:

    获取对象类型

    当然了,这里定义的一个字符串,不用运行,我们也知道类型是String类型,这里只是举个简单的例子,由此我们可以延申,在日常开发中我们可以通过javaClass获取这个对象的类型。

    二、获取对象构造方法:
    为了便于测试,我定义了一个类:

        class Test(name: String,age: Int){
            private val sex: String? = null
    
            constructor(name: String) : this(name,0){
                "my name is $name".p("public constructor:")
            }
    
            private constructor(age: Int) : this("",age){
                "i am $age years old".p("private constructor:")
            }
    
            private fun introduce(name: String,age: Int){
                "my name is $name and i am $age years old".p("private method:")
            }
        }
    

    其中重写了两个构造方法,一个公有的,一个私有的,还定义了一个私有方法和一个私有变量,后面会用到。.p()方法是一个打印扩展方法,如下:

        fun Any.p(tag: String){
            println("$tag -----> $this")
        }
    

    回到正题,先把获取对象构造方法类型以及参数类型的代码贴上,跟着代码讲:

    val test = Test("")
    //获取test对象类型
    val c2 = test.javaClass
    c2.p("222")
    //获取所有构造方法
    val constructors = c2.declaredConstructors
    constructors.forEach {
           //获取构造参数类型
           Modifier.toString(it.modifiers).p("构造函数类型:")
           val paramterTypes = it.parameterTypes
          //获取每个构造参数的每个参数类型
           paramterTypes.forEach { clazz ->
                    "${clazz.name}  ".p("参数类型:")
           }
           "**********".p("")
    }
    

    这里直接new了一个Test对象是为了方便测试,在实际开发中可能是通过调用某个方法获得一个对象。接着通过javaClass获取对象类型,拿到对象类型后,通过declaredConstructors获取这个对象所有的构造方法,每个构造方法再通过modifiers可以获得当前构造方法的类型,是public还是private或者是protect就通过这个方法获取。通过parameterTypes可以获取构造参数类型。运行上述代码结果如下:

    获取构造方法

    第一行打印结果是new对象的时候调用了Test类的第一个构造方法生成的,第二行是test对象类型,后面是对每个构造方法的遍历打印,一共有三个构造方法,而类中我们只定义了两个,那是因为kotlin中直接将参数跟在类名后面会自动生成一个带所有参数的构造方法。通过对比代码和运行结果,也能验证通过declaredConstructors获取构造方法类型和parameterTypes获取构造参数类型的可行性。
    上面是通过declaredConstructors获取所有的构造参数,除此之外还可以通过getDeclaredConstructor(Class<?> parameterTypes)获取特定的构造方法,传入你想要获取的那个构造放的构造参数类型,就可以获得相应的构造方法类型,比如想要获取Test类中定义的私有构造方法,代码如下:

    val intConstructor = c2.getDeclaredConstructor(Int::class.java)
    Modifier.toString(intConstructor.modifiers).p("constructor:")
    

    打印结果:

    获取特定的构造参数类型

    走到这一步,在日常工作中貌似获取构造方法也没什么用,别急,获取构造方法在下一步中会用到。

    三、获取对象实例:
    上一步,我们通过declaredConstructors可以获取所有的构造方法,还可以通过getDeclaredConstructor(Class<?> parameterTypes)获取特定的构造方法,这一步我们通过特定的构造方法,获取对象实例,下面是获取实例的代码:

    val stringConstructor = c2.getDeclaredConstructor(String::class.java)
    stringConstructor.newInstance("张三")
    
    val intConstructor = c2.getDeclaredConstructor(Int::class.java)
    //私有构造方法需要设置这一步
    intConstructor.isAccessible = true
    intConstructor.newInstance(25)
    

    获取到的构造方法通过newInstance(Object ... initargs)方法获得对象实例,传入的值就是构造参数值。这里需要注意的是,私有构造方法需要设置isAccessible = true才可以。下面看下打印结果:

    获取实例

    四、调用私有方法:
    上面是获取构造方法的过程,这一步我们通过对象类型获取类中的私有方法,干货来了。

    val method = c2.getDeclaredMethod("introduce",String::class.java,Int::class.java)
    method.isAccessible = true
    method.invoke(test,"李四",26)
    

    通过getDeclaredMethod(String name, Class<?>... parameterTypes)获取私有方法,第一个参数是你想要获取的方法名,后面传入调用这个方法需要的参数类型。由于是私有方法,所以需要设置isAccessible = true。最后通过invoke() 方法传入反射的对象,第一个参数这里直接传入new出来的test对象,在实际开发中可用newInstance()获得的实例,后面的参数就是私有方法的传参。参数等就实现了私有方法的调用。下面是运行结果:

    调用私有方法

    五、调用私有变量:
    私有方法的调用攻破了,私有变量自然跑不掉,下面是设置私有变量值的代码:

    val declaredField = c2.getDeclaredField("sex")
    declaredField.isAccessible = true
    declaredField.set(test,"女")
    declaredField.get(test).p("sex:")
    

    通过getDeclaredField(String name)传入变量名获取私有变量,私有属性需要设置isAccessible = true,之后通过set(Object obj, Object value)设置变量值,第一个参数是反射的对象,第二个参数就是你要设置的值,最后可以通过get(Object obj)方法获取私有变量值。看下运行结果:

    设置私有变量值

    以上五步就是对java反射基础语法的一个学习和简单运用,从第一步到第五步基本是环环相扣的。下面总结一下:

    1、通过javaClass获取对象类型;
    2、通过对象类型调用getDeclaredConstructor()获取特定的构造方法;
    3、通过构造方法调用newInstance()可以获得对象实例;
    4、通过对象类型调用getDeclaredMethod()获取私有方法,将获取到的实例传入invoke()方法可以完成对私有方法的调用;
    5、调用getDeclaredField()获取私有变量,将获取到的实例传入可以完成对私有变量值的设置。

    以上就是对反射技术的一个学习总结,谢谢阅读。

    相关文章

      网友评论

          本文标题:java反射——基础语法学习

          本文链接:https://www.haomeiwen.com/subject/dbxgyltx.html