精华内容
下载资源
问答
  • 捕获java反射执行方法抛出的异常

    万次阅读 2017-12-07 09:47:04
    一般在业务开发时需要向上层抛异常写法如下:public void A() throws Exception{ throw new Exception(); } public void B(){ ...}但是如果是通过反射调用的A方法那么如果直接catch异常类Exception 会返回nu

    一般在业务开发时需要向上层抛异常写法如下:

    public void A() throws Exception{
      throw new Exception();
    }
    public void B(){
      try{
        A();
      }catch(Exception e){
        //具体处理异常
      }
    }

    但是如果是通过反射调用的A方法那么如果直接catch异常类Exception
    会返回null,所以应该用如下方法捕获:

    public String handleException() {
            String msg = null;
            try {
                Object o = Class.forName("xxx.xxx").newInstance();
                o.getClass().getMethod("").invoke(o);
            } catch (Exception e) {
                if (e instanceof InvocationTargetException) {
                    Throwable targetEx =((InvocationTargetException)e).getTargetException();
                    if (targetEx != null) {
                        msg = targetEx.getMessage();
                    }
                } else {
                    msg = e.getMessage();
                }
            }
            return msg;
        }
    展开全文
  • 这种方法很常用,但是如果采用反射去自动调用某个方法时,却不能捕获到用户自定义的异常。 1.1代码演示如下: 其中BusinessException是自定义异常 定义Man对象,里面的setWork方法抛出自定义BusinessException...

    目录

     

     

    1,问题场景:

    1.1代码演示如下:

    2,问题解决:

    2.1代码演示


     

    1,问题场景:

    我们通常在java开发中采用自定义异常,在业务中遇到非系统错误时抛出自定义异常,并在上层进行捕获,就能知道业务的具体出错信息。这种方法很常用,但是如果采用反射去自动调用某个方法时,却不能捕获到用户自定义的异常。

    1.1代码演示如下:

    其中BusinessException是自定义异常

    定义Man对象,里面的setWork方法抛出自定义BusinessException异常

    package com.cc.utils;
    
    import com.cc.tools.exception.BusinessException;
    
    /** 
    
    * @author 作者 Your-Name:Pxy 
    
    * @version 创建时间:2020年11月26日 下午6:27:00 
    
    * 类说明 
    
    */
    public class Man {
    	 private String work;
    
    	    public String getWork() {
    	        return work;
    	    }
    
    	    public void setWork(String work)  {
    	        this.work = work;
    	        System.out.println(work);
    	        throw new BusinessException("man is died", true);
    	    }
    
    }
    

     main方法利用反射调用Man中的setWork方法,捕获异常

    package com.cc.utils;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import com.cc.tools.exception.BusinessException;
    
    /**
     * 
     * @author 作者 Your-Name:Pxy
     * 
     * @version 创建时间:2020年11月26日 下午6:26:19
     * 
     *          类说明
     * 
     */
    public class TestDemo {
    
    	public static void main(String[] args) {
    		Method method = null;
    		try {
    			method = Man.class.getMethod("setWork", String.class);
    		} catch (NoSuchMethodException | SecurityException e) {
    			e.printStackTrace();
    		}
    		Man man = new Man();
    
    		try {
    			method.invoke(man, "man is hard working");
    		} catch (Exception e) {
    	          System.out.println("ok,we catch SimpleException:"+e);
    	            
    		}
    
    	}
    
    }
    

    打印结果

    man is hard working
    ok,we catch SimpleException:java.lang.reflect.InvocationTargetException

     

    2,问题解决:

    这里我们看到异常被捕捉到了,但是打印的异常不是 BusinessException异常,而是反射异常。这是为什么呢?其实java认为用反射来调用方法时,jvm不能在编译期间确定方法的throws 类型,所以方法可能抛出的异常jvm也不能动态确定其类型,而统一抛出InvocationTargetException。那么我们怎么修改以上代码能正确地获取到业务抛出的异常信息呢?这里我们给出一个重要的方法,getCause()方法。getCause()返回此异常的原因(尝试加载类时发生错误引发的异常;否则返回 null)

    2.1代码演示

    那么,我们修改main方法如下

    package com.sgcc.utils;
    
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    import com.sgcc.tools.exception.BusinessException;
    
    /**
     * 
     * @author 作者 Your-Name:Pxy
     * 
     * @version 创建时间:2020年11月26日 下午6:26:19
     * 
     *          类说明
     * 
     */
    public class TestDemo {
    
    	public static void main(String[] args) {
    		Method method = null;
    		try {
    			method = Man.class.getMethod("setWork", String.class);
    		} catch (NoSuchMethodException | SecurityException e) {
    			e.printStackTrace();
    		}
    		Man man = new Man();
    
    		try {
    			method.invoke(man, "man is hard working");
    		} catch (Exception e) {
    
    			  Throwable cause = e.getCause();
    	          System.out.println("ok,we catch SimpleException:"+cause);
    	            
    		}
    
    	}
    
    }
    

     

    执行结果如下:

    man is hard working
    ok,we catch SimpleException:com.sgcc.tools.exception.BusinessException: man is died

    捕捉到原方法中的 BusinessException异常

    展开全文
  • 反射调用方法,报空指针异常

    千次阅读 2018-11-14 11:25:55
    @Component public class OSSUtil { private static Logger log = LoggerFactory....PostConstruct在构造函数之后执行,init()方法之前执行(详见: https://www.cnblogs.com/qingruihappy/p/7861623.html )  
    @Component
    public class OSSUtil {
    private static Logger log = LoggerFactory.getLogger(OSSUtil.class);
    
        private static  OSSUtil ossUtil;
    
        @Autowired
        private OSSProperties ossProperties;
    
        @PostConstruct
        public void init(){
            log.info("初始化开始");
            ossUtil = this;
            ossUtil.ossProperties = this.ossProperties;
           
    
    
        }
    
        private static volatile OSSClient ossClient;
    
        public static OSSClient getInstance(){
            if(ossClient == null){
               
                ossClient = new OSSClient(ossUtil.ossProperties.getEndpoint(),ossUtil.ossProperties.getAccessKeyId(),ossUtil.ossProperties.getAccessKeySecret());
    
              
            }
            return ossClient;
        }

     

    调用方法ossUtil.ossProperties.getEndpoint() 报空

    解决方法:在init方法上加 @PostConstruct注解

    @PostConstruct解释:

    @PostConstruct修饰的方法会在服务器加载Servle的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行(详见:https://www.cnblogs.com/qingruihappy/p/7861623.html

     

    展开全文
  • 要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。 getMethods() getMethods(String name,Class<?> …parameterTypes) getDeclaredMethods() ...

    动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。

    • getMethods()
    • getMethods(String name,Class<?> …parameterTypes)
    • getDeclaredMethods()
    • getDeclaredMethods(String name,Class<?>...parameterTypes)


    如果是访问指定的构造方法,需要根据该方法的入口参数的类型来访问。例如,访问一个名称为 max,入口参数类型依次为 int 和 String 类型的方法。

    下面的两种方式均可以实现:

     
    1. objectCiass.getDeclaredConstructor("max",int.class,String.class);
    2. objectClass.getDeclaredConstructor("max",new Ciass[]{int.class,String.class});


    Method 类的常用方法如表 3 所示。
     

    表1 Method类的常用方法
    静态方法名称说明
    getName().获取该方法的名称
    getParameterType()按照声明顺序以 Class 数组的形式返回该方法各个参数的类型
    getRetumType()以 Class 对象的形式获得该方法的返回值类型
    getExceptionTypes()以 Class 数组的形式获得该方法可能抛出的异常类型
    invoke(Object obj,Object...args)利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型
    isVarArgs()查看该方法是否允许带有可变数量的参数,如果允许返回 true,否 则返回 false
    getModifiers()获得可以解析出该方法所采用修饰符的整数

    例 2

    下面通过一个案例来演示如何调用 Method 类的方法获取动态类中方法的信息。

    (1) 首先创建一个 Book1 类,并编写 4 个具有不同作用域的方法。Book1 类的最终代码如下:

     
    1. package ch12;
    2. public class Book1
    3. {
    4. //static 作用域方法
    5. static void staticMethod()
    6. {
    7. System.out.println("执行staticMethod()方法");
    8. }
    9. //public 作用域方法
    10. public int publicMethod(int i)
    11. {
    12. System.out.println("执行publicMethod()方法");
    13. return 100+i;
    14. }
    15. //protected 作用域方法
    16. protected int protectedMethod(String s,int i)throws NumberFormatException
    17. {
    18. System.out.println("执行protectedMethod()方法");
    19. return Integer.valueOf(s)+i;
    20. }
    21. //private 作用域方法
    22. private String privateMethod(String ...strings)
    23. {
    24. System.out.println("执行privateMethod()方法");
    25.  
    26. StringBuffer sb=new StringBuffer();
    27. for(int i=0;i<sb.length();i++)
    28. {
    29. sb.append(strings[i]);
    30. }
    31. return sb.toString();
    32. }
    33. }


    (2) 编写测试类 Test02,在该类的 main() 方法中通过反射访问 Book1 类中的所有方法,并将该方法是否带可变类型参数、入口参数类型和可能拋出的异常类型信息输出到控制台。

    Test02 类的代码如下:

     
    1. package ch12;
    2. import java.lang.reflect.Constructor;
    3. import java.lang.reflect.Field;
    4. import java.lang.reflect.Method;
    5. public class Test02
    6. {
    7. public static void main(String[] args)
    8. {
    9. //获取动态类Book1
    10. Book1 book=new Book1();
    11. Class class1=book.getClass();
    12. //获取Book1类的所有方法
    13. Method[] declaredMethods= class1.getDeclaredMethods();
    14. for(int i=0;i<declaredMethods.length;i++)
    15. {
    16. Method method=declaredMethods[i];
    17. System.out.println("方法名称为:"+method.getName());
    18. System.out.println("方法是否带有可变数量的参数:"+method.isVarArgs());
    19. System.out.println("方法的参数类型依次为:");
    20. //获取所有参数类型
    21. Class[] methodType=method.getParameterTypes();
    22. for(int j=0;j<methodType.length;j++)
    23. {
    24. System.out.println(" "+methodType[j]);
    25. }
    26. //获取返回值类型
    27. System.out.println("方法的返回值类型为:"+method.getReturnType());
    28. System.out.println("方法可能抛出的异常类型有:");
    29. //获取所有可能抛出的异常
    30. Class[] methodExceptions=method.getExceptionTypes();
    31. for(int j=0;j<methodExceptions.length;j++)
    32. {
    33. System.out.println(" "+methodExceptions[j]);
    34. }
    35. boolean isTurn=true;
    36. while(isTurn)
    37. {
    38. try
    39. { //如果该成员变量的访问权限为private,则抛出异常
    40. isTurn =false;
    41. if(method.getName().equals("staticMethod"))
    42. { //调用没有参数的方法
    43. method.invoke(book);
    44. }
    45. else if(method.getName().equals("publicMethod"))
    46. { //调用一个参数的方法
    47. System.out.println("publicMethod(10)的返回值为:"+method.invoke(book,10));
    48. }
    49. else if(method.getName().equals("protectedMethod"))
    50. { //调用两个参数的方法
    51. System.out.println("protectedMethod(\"10\",15)的返回值为:"+method.invoke(book,"10",15));
    52. }
    53. else if(method.getName().equals("privateMethod"))
    54. { //调用可变数量参数的方法
    55. Object[] parameters=new Object[]{new String[]{"J","A","V","A"}};
    56. System.out.println("privateMethod()的返回值为:"+method.invoke(book,parameters));
    57. }
    58. }
    59. catch (Exception e)
    60. {
    61. System.out.println("在设置成员变量值时抛出异常,下面执行setAccessible()方法");
    62. method.setAccessible(true); //设置为允许访问private方法
    63. isTurn = true;
    64.  
    65. }
    66. }
    67. System.out.println("=============================\n");
    68. }
    69. }
    70. }


    (3) 运行测试类 test02,程序将会依次动态访问 Book1 类中的所有方法。访问 staticMethod() 方法的运行效果如下所示:

    方法名称为:staticMethod
    方法是否带有可变数量的参数:false
    方法的参数类型依次为:
    方法的返回值类型为:void
    方法可能抛出的异常类型有:
    执行staticMethod()方法
    =============================


    访问 publicMethod() 方法的运行效果如下所示:

    方法名称为:publicMethod
    方法是否带有可变数量的参数:false
    方法的参数类型依次为:
    int
    方法的返回值类型为:int
    方法可能抛出的异常类型有:
    执行publicMethod()方法
    publicMethod(10)的返回值为:110
    =============================


    访问 protectedMethod() 方法的运行效果如下所示:

    方法名称为:protectedMethod
    方法是否带有可变数量的参数:false
    方法的参数类型依次为:
    class java.lang.String
    int
    方法的返回值类型为:int
    方法可能抛出的异常类型有:
    class java.lang.NumberFormatException
    执行protectedMethod()方法
    protectedMethod("10",15)的返回值为:25
    =============================


    访问 privateMethod() 方法的运行效果如下所示:

    方法名称为:privateMethod
    方法是否带有可变数量的参数:true
    方法的参数类型依次为:
    class java.lang.String;
    方法的返回值类型为:class java.lang.String
    方法可能抛出的异常类型有:
    在设置成员变量值时抛出异常,下面执行setAccessible()方法
    执行privateMethod()方法
    privateMethod()的返回值为:
    =============================
    展开全文
  • Java的反射是好东西,很多框架都用到...以上种类的代码时候,当然我是故意这样的,方法内也没try catch,不是要讨论这种异常产生的原因, 那么method.invoke所在的try...catch,是捕获不到这类异常的。 这要怎么解决?
  • Map,Object> map=responseModel.getResponseMap(); //组织参数 Map[] argsClass = new Map[1]; argsClass[0] = map; responseModel = (ResponseModel) invokeMethod(ivkClass, "demo1", ...
  • 反射方法报空指针异常

    千次阅读 2019-09-21 08:46:57
    出现空指针的原因:当通过反射方法时,spring注入的对象获取不到即为null。 案例一: //获取AServiceImpl的字节码对象 Class clazz = AServiceImpl.class; //创建AServiceImpl对象 AServiceImpl serviceImpl = ...
  • Java利用反射获取方法执行

    万次阅读 2018-04-17 11:30:33
    java的反射用法:①找到类:Class cl = Class.forName("java.util.Date");//获取类信息②创建对象(要求这个类中含有空参数的构造方法):Object obj = cl.newInstence();③根据名称和参数找方法:Method ...
  • C# 反射执行指定方法名/重载

    千次阅读 2018-01-25 19:48:00
    Type.InvokeMember 方法 1. 主方法 class Program { static void Main(string[] args) { ReflectUtils rf = new ReflectUtils();... rf.FNCMethod("ToString", null);//执行类中重写的ToString
  • 笔者前些日子做过一个这样的事情,利用反射机制调用一个会报Checked的异常方法,在调用后没法抛出异常(原因是反射机制调用是没法catch到Checked异常的)。举个简单的例子如下。  1.先定义一个简单的异常类(这样...
  • 这种方法很常用,但是如果采用反射去自动调用某个方法时,却不能捕获到用户自定义的异常。下面用代码来说明: /** * WebException为自定义异常 */ class Foo{   public void fun(int n) throws ...
  • 利用Java反射机制去调用其他类的main方法基于这种情形: 当程序中的某个类在运行到某处需要去调用其他类的main方法时,如果此程序并不知道此main方法所属类的名称,而只是在程序中接受某一代表此main方法所属类的...
  • Java第九篇反射异常处理

    千次阅读 2018-07-05 00:29:17
    跟的是异常对象, 只能抛出一个异常对象名, 表示抛出异常,由方法体内的语句处理,执行throw一定抛出了某种异常异常处理方法B:运行时系统寻找相应的代码来处理这一异常,系统在方法的调用栈中查找,从产生异常...
  • 使用反射调用方法

    千次阅读 2019-07-10 21:14:39
    // 通过Method的invoke方法执行setter方法, // 将config.getProperty(name)的值作为调用setter的方法的参数 mtd.invoke(target, config.getProperty(name)); } } } public Object getObject( String name )...
  • 在 Java 中如果我们使用 new 关键字调用构造函数对类进行实例化,我们就可以根据在这个类中的修饰符来访问类中定义的非私有方法。但是如果需要在其他类调用私有的方法,就可以利用 Java 中提供的反射来实现。
  • Java基础知识面试题(2020最新版)

    万次阅读 多人点赞 2020-02-19 12:11:27
    Java获取反射的三种方法 网络编程 常用API String相关 字符型常量和字符串常量的区别 什么是字符串常量池? String 是最基本的数据类型吗 String有哪些特性 String为什么是不可变的吗? String真的是不可变的吗? ...
  • Java通过反射调用一个类的私有方法

    万次阅读 多人点赞 2018-07-13 11:50:17
    获得私有方法的流程是 (1)获取目标类 (2)获取目标方法  Method method=clazz.getDeclaredMethod(name);//可以调用类中的所有方法(不包括父类中继承的方法)  Method method=clazz.getMethod(name);//...
  • 反射
  • java反射invoke调用方法报空指针异常

    千次阅读 2018-09-10 20:16:55
    最近做项目用到定时任务,在...在执行invoke方法的时候,一直报空指针异常,百度了一下午才找到解决方案。现在把解决方法分享给大家。   先看下代码: 首先是一个测试类: @Test public void test() { Str...
  • 需求:现在有一群service接口,有同一个方法名称,内部逻辑除了调用不同的调用自身的方法外其他基本都一致,那现在就需要一个独立的方法来勾勒出这个方法 1.SpringContextUtil package com.XXX.report.util; ...
  • java反射异常

    千次阅读 2017-10-19 18:08:39
    java.lang.RuntimeException: 方法执行失败 at cn.zhang.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:42) at cn.zhang.Test1.test03(Test1.java:39) at sun.reflect.NativeMethodAccessorImpl.invoke0...
  • 反射方式调用enum的方法

    万次阅读 2018-11-07 15:43:23
    代码中存在很多结构相似的枚举,需要分别调用其方法名称相同的方法,所以选择使用反射调用 枚举代码如下: package com.ruisitech.bi.enums.bireport; /** * @author:mazhen * @date:2018/9/13 11:46: * @...
  • springMVC 通过反射调用类方法

    千次阅读 2018-02-05 14:05:07
    通过反射方法调用类中的方法 适用于递归类执行方法操作 减少代码冗余
  • 反射获取方法返回结果

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

    万次阅读 多人点赞 2019-11-26 11:59:06
    执行的结果: str1:1179395 | str2:1179395 false 代码解读:很显然“通话”和“重地”的 hashCode() 相同,然而 equals() 则为 false,因为在散列表中,hashCode()相等即两个键值对的哈希值相等,然而哈希值相等...
  • 反射工具类(调用父类的方法和字段)

    千次阅读 2017-06-05 21:48:28
    使用这个工具类,可以完成父类,基类,方法,字段,无论什么权限都可以调用.package com.reflect; /** * 基类 * @author jianghui */ public class GrandParent { public String publicField = "1"; String ...
  • 以上方法在 TrustPayCommand 类中,通过反射执行@Service("wyBaseCommand")类中的getSpecialAccount(String accName)方法。 public JsonResultVO getSpecialAccount(WyCompanyInDataBean inDataBean) { // 此...
  • 1.方法定义成public类型. 2.getMethod传参要正确 比如调用定义的:publicvoid show(Object obj) 要这样调用 clazz.getMethod("show",Object.class);而不是obj.class 3.invoke时invoke(this,obj) 传参要正确,看好...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 119,465
精华内容 47,786
关键字:

反射执行方法异常