首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >反射类的方法

反射类的方法

原创
作者头像
MonroeCode
发布2018-01-11 12:25:47
发布2018-01-11 12:25:47
1.6K0
举报
文章被收录于专栏:Java技术分享Java技术分享

关于对类的方法的反射。其中包括静态方法,普通方法,带参数的方法,以及最重要的String[]数组的方法的反射以及需要注意的细节问题,都是基础,所以请各位多多包涵!

首先,通过Class获取类的字节码

Class clazz = Class.forName("com.marer.reflect.Person");

1.反射无参的方法: public void aa1()

Method method = clazz.getMethod("aa", null);

第一个参数:方法名;第二个参数:方法的参数,若为无参方法可以为null值

执行方法:

method.invoke(p, null);//第一个参数:你要调用哪个对象的方法,假设new了一个新的对象p;第二个参数:被反射的对象的方法所需要的参数,如果无参数则传null

2.反射带一个或者多个参数的方法: public void aa(String name, int age)

Method method = clazz.getMethod("aa", String.class, int.class);//第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用

第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用

执行方法:

method.invoke(p, "老张,成功了", 23);//第一个参数:你要调用哪个对象的方法,假设new了一个新的对象p;第二个参数:可变参数

3.反射带数组的方法,并返回Class数组: public Class[] aa(String name, int[] ages)

Method method = clazz.getMethod("aa", String.class, int[].class);//在这里,原方法第二个参数中是个int数组,那么就传int[].class

执行方法:

Class cs[] = (Class[]) method.invoke(p, "老李,成功了", new int[]{1,2,3});

4.反射类的私有方法: private void aa(InputStream in)

Method method = clazz.getDeclaredMethod("aa", InputStream.class);//private方法用getDeclaredMethod()

method.setAccessible(true);//打开访问权限,暴力反射

执行方法:

Class cs[] = (Class[]) method.invoke(p, new FileInputStream("D:\\我的文档\\Q.txt"));

5.反射类的静态方法: public static void aa(int num)

Method method = clazz.getMethod("aa", int.class);

执行方法:

method.invoke(123);//静态方法调用不需要对象,直接执行

与普通方法不同,在静态方法中,因为静态方法是一直存在的,因此不需要通过对象的访问进行调用,只需要直接调用

而需要通过对象调用的普通方法,执行的是对象内部的方法,对其他的对象没有影响

6.反射类的main方法,以及有且只有一个参数并且参数类型为数组的方法的反射、特殊的参数String[] 的反射方法: 

public static void main(String[] args)

public static boolean doDelete(int[] ids)

反射:

Method method = clazz.getMethod("main", String[].class);//这里指定方法名为main,指定参数为String[]数组

执行方法一:

method.invoke(null, new Object[]{new String[]{"123","weq"}});//第一种方法,将String[]数组参数包装在数组中,到了invoke()里面就会对应拆分出一个String数组

执行方法二:

method.invoke(null, (Object) new String[]{"123","weq"});//第二种方法,推荐使用,将参数的数组包装在一个Object中,并且由JDK拆分,拆分出第一个参数就是数组,那么就会通过调用

//注意:这里将String[]数组参数封装为(Object)对象是允许的因为Object对象是所有对象的始祖

注意:1.上面的main方法的反射以及调用,适用所有的有且只有一个String[]数组为参数的方法,对于其他类型的数组可以不用包装,例如只有一个int[]参数的方法

method.invoke(null, new int[]{1,2});//如果只有一个int[]数组为参数的反射,可以不用像上面那样封装,即使封了也没问题invoke(null, (Object)new int[]{1,2})

注意:2.对于String和包装类(例如:Integer,Charater..),如果一个或多个参数都是同样的(String或包装类),就可以通过new 数组的形式进行invoke反射调用,例如:

1.一个或多个String参数,必须都是String,如果有一个参数不一样(例如String和String[]数组都是不一样的,那么就不能够通过下面的方法进行反射调用方法

类方法:public static void test(String s1, String s2)

反射方法:Method method = clazz.getMethod("test", String.class, String.class);

反射方法的invoke调用:method.invoke(null, new String[]{"asd","123"});

//当然,上面的也可以通过普通的两个个字符串参数进行invoke调用

2.一个或多个包装类的方法都是一样的:(Integer,Character...)

类方法:public static void test6(Integer a1, Integer a2)

反射方法:Method method = clazz.getMethod("test6", Integer.class,Integer.class);

反射方法的invoke调用:method.invoke(null, new Integer[]{1,2});

//必须注意:两个基础数据类型的int不能通过数组进行invoke反射调用,乖乖地一个个传参吧

//Method method = clazz.getMethod("test4", int.class,int.class);

//method.invoke(null, 1,2);

3.但是对于两个或以上的String[]数组声明的方法就不可以用一个数组进行invoke调用

类方法:public static void test8(String[] s1, String[] s2)

反射方法:Method method = clazz.getMethod("test8", String[].class, String[].class);

反射方法的invoke调用:method.invoke(null, new String[]{"abc","def"});//这时候是抛出参数要求长度不一的异常的

//运行结果是抛异常的,因此证明是不能通过这种方法去进行invoke调用

4.普通类也不能通过数组的方式进行invoke调用

类方法:public static void test7(Person p1, Person p2)

反射方法:Method method = clazz.getMethod("test7", Person.class,Person.class);

反射方法的invoke调用:method.invoke(null, new Person(),new Person());//两个非String或非包装类就不能用数组来invoke反射调用

本文由机智猫亲手写,转载请尊重版权:http://blog.csdn.net/nthack5730/article/details/49888833

总结:通过上述几个样例,大家应该可以看到反射方法的invoke调用的不同的形式

        其实只要注意有且只有一个String[]数组作为参数的方法的反射以及调用注意的问题就可以了【直接将String[]数组的参数强转成Object即可】

除了多个String参数或多个包装类型的方法(都必须都是String类型的参数或包装类型)可以通过在invoke的时候传一个String[]数组参数以外

其他方法都是必须按照参数的要求对号入座

PS.一般情况为了避免造成不必要的麻烦,都建议按照参数的个数要求进行对号入座

关于之前写的Person类:

代码语言:js
复制
package com.marer.reflect;  
  
import java.io.InputStream;  
import java.util.List;  
  
public class Person {  
    public String str = "aa";  
    int a = 1233;  
    private int num = 4564564;  
    private static int num2 = 9527;  
    private int nums;  
    private String name;  
      
      
    public Person(){  
        System.out.println("person");  
    }  
      
    public Person(String name){  
        System.out.println("person name:" + name);  
    }  
      
    public Person(String name, int age){  
        System.out.println("person name:" + name + "\tage:" + age);  
    }  
      
    private Person(List list){  
        System.out.println("list");  
    }  
      
      
    //方法  
      
    public void aa(){  
        System.out.println("aa");  
    }  
      
    public void aa(String name, int age){  
        System.out.println("person name:" + name + "\tage:" + age);  
    }  
      
    public Class[] aa(String name, int[] ages){  
        System.out.println("有返回值的");  
        return new Class[]{String.class};  
    }  
      
    private void aa(InputStream in){  
        System.out.println(in);  
    }  
      
    public static void aa(int num){  
        System.out.println(num);  
    }  
      
      
    public static void main(String[] args){  
        System.out.println("main方法运行");  
    }  
      
      
    public static void test(String[] args){  
        System.out.println("字符串数组参数方法调用成功");  
    }  
      
    public static void test(String s1, String s2){  
        System.out.println("两个字符串");  
        System.out.println(s1);  
        System.out.println(s2);  
    }  
      
    public static void test_1(String s1, String s2,String s3){  
        System.out.println("三个字符串");  
        System.out.println(s1);  
        System.out.println(s2);  
        System.out.println(s3);  
    }  
      
    public static void test2(int[] a1, int[] a2){  
        System.out.println("两个参数为数组的方法");  
        System.out.println(a1.length);  
        for(int a: a1){  
            System.out.print(a+",");  
        }  
        System.out.println("\n"+a2.length);  
        for(int a: a2){  
            System.out.print(a+",");  
        }  
    }  
      
    public static void test3(int[] a1, int a2){  
        System.out.println("第一个参数为数组,第二个参数为普通类型的方法");  
        System.out.println(a1.length);  
        for(int a: a1){  
            System.out.print(a+",");  
        }  
        System.out.println(a2);  
    }  
      
      
    public static void test4(int a1, int a2){  
        System.out.println("两个参数为普通类型int,用数组进行invoke");  
        System.out.println(a1);  
        System.out.println(a2);  
    }  
      
    public static void test5(int[] a1){  
        System.out.println("int 数组");  
        for(int a:a1){  
            System.out.println(a);  
        }  
    }  
      
    public static void test6(Integer a1, Integer a2){  
        System.out.println("两个参数为普通类型Integer,用数组进行invoke");  
        System.out.println(a1);  
        System.out.println(a2);  
    }  
      
    public static void test7(Person p1, Person p2){  
        System.out.println("两个参数为普通类型Integer,用数组进行invoke");  
        System.out.println(p1);  
        System.out.println(p2);  
    }  
      
      
    public static void test8(String[] s1, String[] s2){  
        System.out.println("两个字符串数组");  
        System.out.println(s1.toString());  
        System.out.println(s2.toString());  
    }  
  
    public int getNum() {  
        return num;  
    }  
  
    public void setNum(int num) {  
        this.num = num;  
    }  
  
    public static int getNum2() {  
        return num2;  
    }  
  
    public static void setNum2(int num2) {  
        Person.num2 = num2;  
    }  
  
    public int getNums() {  
        return nums;  
    }  
  
    public void setNums(int nums) {  
        this.nums = nums;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
}  

这次本文的Demo类:

代码语言:js
复制
package com.marer.reflect;  
  
import java.io.FileInputStream;  
import java.io.InputStream;  
import java.lang.reflect.Method;  
  
import org.junit.Test;  
  
//反射类的方法  
public class Demo3 {  
      
    //反射类的方法:public void aa1()  
    @Test  
    public void test1() throws Exception{  
          
        Person p = new Person();  
          
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("aa", null);//第一个参数:方法名;第二个参数:方法参数  
          
        method.invoke(p, null);//第一个参数:你要调用哪个对象的方法;第二个参数:被反射的对象的方法所需要的参数  
          
    }  
      
      
      
    //反射类的方法:public void aa(String name, int age)  
    @Test  
    public void test2() throws Exception{  
          
        Person p = new Person();  
          
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("aa", String.class, int.class);//第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用  
          
        method.invoke(p, "老张,成功了", 23);//第一个参数:你要调用哪个对象的方法;第二个参数:可变参数  
          
    }  
      
      
    //反射类的方法:public Class[] aa(String name, int[] ages)  
    @Test  
    public void test3() throws Exception{  
          
        Person p = new Person();  
          
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("aa", String.class, int[].class);//在这里,原方法第二个参数中是个int数组,那么就传int[].class  
          
        Class cs[] = (Class[]) method.invoke(p, "老李,成功了", new int[]{1,2,3});  
          
        System.out.println(cs[0]);  
    }  
      
      
      
    //反射类的私有方法:private void aa(InputStream in)  
    @Test  
    public void test4() throws Exception{  
          
        Person p = new Person();  
          
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getDeclaredMethod("aa", InputStream.class);//private方法用getDeclaredMethod()  
          
        method.setAccessible(true);//打开访问权限,暴力反射  
          
        Class cs[] = (Class[]) method.invoke(p, new FileInputStream("D:\\我的文档\\Q.txt"));  
    }  
      
      
      
    //反射类的静态方法:public static void aa(int num)  
    @Test  
    public void test5() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("aa", int.class);  
        method.invoke(123);//静态方法调用不需要对象  
    }  
      
      
      
    //反射类的方法:public static void main(String[] args)  
    @Test  
    public void test6() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("main", String[].class);//这里指定方法名为main,指定参数为String[]数组  
          
//      method.invoke(null, new Object[]{new String[]{"123","weq"}});//第一种方法,将String[]数组参数包装在数组中,到了invoke()里面就会对应拆分出一个String数组  
        method.invoke(null, (Object) new String[]{"123","weq"});//第二种方法,推荐使用,将参数的数组包装在一个Object中,并且由JDK拆分,拆分出第一个参数就是数组,那么就会通过调用  
          
        //main方法的反射获取和调用  
    }  
      
      
      
    //反射类方法:public static void test(String[] args)  
    @Test  
    public void test7() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test", String[].class);  
          
        method.invoke(null, (Object) new String[]{"asd","123"});  
          
    }  
      
      
    //反射类方法:public static void test(String s1, String s2)  
    @Test  
    public void test8() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test", String.class, String.class);  
  
        method.invoke(null, new String[]{"asd","123"});  
          
    }  
      
      
    //反射类方法:public static void test_1(String s1, String s2, String s3)  
    @Test  
    public void test8_1() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test_1", String.class, String.class,String.class);  
  
        method.invoke(null, new String[]{"asd","123","456"});  
          
    }  
      
      
    //反射类方法:public static void test2(int[] a1, int[] a2)  
    @Test  
    public void test9() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test2", int[].class,int[].class);  
          
        method.invoke(null, new int[]{1,2,3},new int[]{4,5,6});  
    }  
      
      
    //反射类方法:public static void test3(int[] a1, int a2)  
    @Test  
    public void test10() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test3", int[].class,int.class);  
          
        method.invoke(null, new int[]{1,2,3},4);  
    }  
      
      
    //反射类方法:public static void test4(int a1, int a2)  
    @Test  
    public void test11() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test4", int.class,int.class);  
          
        method.invoke(null, 1,2);//两个基础数据类型的int不能通过数组进行invoke反射调用,乖乖地一个个传参吧  
    }  
      
      
    //反射类方法:public static void test5(int[] a1)  
    @Test  
    public void test12() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test5", int[].class);  
          
        method.invoke(null, new int[]{1,2});  
    }  
      
      
    //反射类方法:public static void test6(Integer a1, Integer a2)  
    @Test  
    public void test13() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test6", Integer.class,Integer.class);  
          
        method.invoke(null, new Integer[]{1,2});//两个基础数据类型的int不能通过数组进行invoke反射调用  
    }  
      
      
      
    //反射类方法:public static void test7(Person p1, Person p2)  
    @Test  
    public void test14() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test7", Person.class,Person.class);  
          
        method.invoke(null, new Person(),new Person());//两个非String或非包装类就不能用数组来invoke反射调用  
    }  
      
      
    //反射类方法:public static void test8(String[] s1, String[] s2)  
    @Test  
    public void test15() throws Exception{  
        Class clazz = Class.forName("com.marer.reflect.Person");  
        Method method = clazz.getMethod("test8", String[].class, String[].class);  
        method.invoke(null, new String[]{"abc","def"});//运行结果是抛异常的  
    }  
      
}  

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档