什么是反射?当newInstance的时候,所遇到的空指针问题

本文介绍了Java反射的基本概念及其在获取私有成员方面的应用,并详细探讨了反射在Spring框架中的集成问题,包括如何解决@Autowired失效的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

前一阵子,给公司内部做了一个网络管理的系统,对调用交换机获取数据,需要一些提前定制化的检测方法。所以使用了反射,同时也有一个问题困扰了我一天,下面先说说反射。

正文

什么是反射?

在java工程中,对任意一个运行中的对象,可以调用其任意属性及方法,这就是反射。

一般情况下,根据面向对象封装原则,Java实体类的属性都是私有的,我们不能获取类中的属性。但我们可以根据反射,获取私有变量、方法、构造器,甚至是注解。

如何使用?

可以参考这篇文章,特别详细,我就不多说了:
https://zwz99.blog.youkuaiyun.com/article/details/109248009

newInstance的问题?

在使用反射的过程中,遇到了@Autowired失效的问题,想到可能是反射获得的类并没有由spring容器管理,所以造成了null pointer,空指针问题。

		Class<?> taskTypeClass = Class.forName("方法的名字");
		//出错的地方
        Object taskTypeInstance = taskTypeClass.newInstance();
        
        Method taskTypeClassMethod = taskTypeClass.getDeclaredMethod(taskType.getMethodName());

        //返回值
        Object invoke = taskTypeClassMethod.invoke(taskTypeInstance);

原因就是在这个方法的内部,虽然可以拿到方法,但如果类里面使用了@Autowird,就会得到空了,
因为,class.newInstance() 这个方法,没有和spring关联起来获取Bean

知道问题,那就不用反射的方式获取了,直接用spring的上下文获取就可以了,

@Component
public class ApplicationContextHelper implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        applicationContext = context;
    }

    /**
     * 获取bean
     */
    public static <T> T popBean(Class<T> clazz) {
        //先判断是否为空
        if (applicationContext == null) {
            return null;
        }
        return applicationContext.getBean(clazz);
    }
    
}

将class.newInstance()活成上面的方法就可以了!

Spring会检测容器中所有的Bean,当Spring发现某个Bean实现了ApplicationContextAware接口,Spring会在创建Bean后,自动调用setApplicationContextAware()的方法。

当调用他时,会将容器本身当作参数传递给这个方法,赋值给该类的applicationContext实例,所以就可以这个实例来访问其本身了。

白话说,要借助spring实现某个功能,必须让Bean找到Spring才能用。
比如说,反射的 newInstance() 没和 Spring 关联,那就直接用Spring的方式,告诉调用这个功能的人,我处理过了,你可以用了。
这个处理的人就是Spring的接口ApplicationContextAware

总结

反射这个东东,看起来很简单,实际上他掺杂了很多关于java底层的东西,为什么他可以获取所有运行中的对象?嗯,需要深入了解下!

参考文章:https://blog.youkuaiyun.com/hao134838/article/details/103537443

希望对大家有点帮助!我是阿昊,一个独自在大城市努力的年轻人。

当你尝试通过`JaxWsDynamicClientFactory.newInstance().createClient(wsdlUrl)`创建WebService客户端并遇到"空指针异常"(NullPointerException),这通常意味着工厂实例可能尚未初始化,或者传递给`wsdlUrl`的URL无效。JAX-WS(Java API for XML Web Services)动态客户端是基于WSDL(Web服务描述语言)来生成的,如果其中任何一个环节出现问题,都可能导致这个错误。 解决这个问题的步骤可能包括: 1. **检查工厂**:确保你已经正确地创建了`JaxWsDynamicClientFactory`实例,并且它没有被设置为null。如果没有初始化,需要先调用`JaxWsDynamicClientFactory.newInstance()`。 ```java JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); ``` 2. **验证URL**:`wsdlUrl`可能是空字符串、null或其他非存在的地址,确保提供的WSDL文件路径或URL是有效的。 3. **处理异常**:在创建客户端时,可以添加适当的异常处理代码来捕获并处理可能出现的`NullPointerException`,例如: ```java try { WebServiceFeature[] features = ...; // 如果需要,配置其他特性 WebServiceClient client = factory.createClient(wsdlUrl, features); } catch (NullPointerException e) { System.err.println("Error: " + e.getMessage()); } ``` 4. **日志和调试**:记录详细的错误信息,这对于查找问题原因非常有帮助。 如果你遇到此类问题,记得检查相关的API文档和示例,确认你的代码是否按照规范执行。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿昊丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值