JAVA 注入比 使用static方法优点在哪里呢

zyq654321 2021-01-19 09:54:21
都是随时可以用,费那么大劲搞注入,怎么也想不明白,那位大神能用简单的语言解释一下,或者转发一些文章也可以
...全文
1095 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰思雨 2021-04-09
  • 打赏
  • 举报
回复 1
注入关注的是对象的生命周期,static 关注的是全局共享。 两者具有不同的特点。 static 声明的对象是全局共享的,当所属类被加载后,生命周期布满整个所属类。只有所属类被卸载时静态变量才会被回收。 注入的对象,只有在使用的时候被使用和被依赖的时候才会被创建,创建过程也可以插入一些初始化操作的代码,对象的回收不是在所属类被卸载的时候发生,而是看垃圾回收机制是否满足回收的条件,并且回收前也可以插入一些是否资源的代码。 注入的对象,当配置文件变更后,或者有新的配置文件加入后,可以进行 reload 操作,不用重启项目。 优点嘛,也就是这些。 全局共享的对象,使用起来方便,没有什么学习成本。但是,由于回收麻烦,项目大了的话,占着内存放不掉,很是闹心。并且,全局的访问权限,随处可以更改对象内容,也有线程安全的隐患。 注入的对象,声明周期的把控相对很到位,项目大了的话,内存不足时,垃圾回收机制可以起到一定的作用,相对来讲,比全局对象要好些,但是,实际应用场景中,由于默认都是单例的对象,垃圾回收并没有太大的区别。但是,对象数据的封装性仍然会被体现出来,不是全局的对象,访问起来就必须靠依赖关系才可以,这样做是非常棒的,商业项目中,项目会分层分模块开发,避免公司的资源泄露,公司资源包括源代码和数据。 总之,注入的方式,使用了内存管理方面的技术;静态的方式全局可见。
1100101001 2021-04-09
  • 打赏
  • 举报
回复
超市买东西为什么需要进账,为什么不直接收钱就行呢,一个道理
qq_41184054 2021-04-07
  • 打赏
  • 举报
回复
使用java为的就是他面向对象的优势,效率什么的都是其次。注入的好处等你工作了或者真正接触项目开发之后自然会懂,现在只要知道哪个好就行
yifeiyuann 2021-01-29
  • 打赏
  • 举报
回复
谢谢分享,收藏
xiaoxiangqing 2021-01-27
  • 打赏
  • 举报
回复
我觉得最大的区别,就是注入里可以再注入,
小灰狼 2021-01-27
  • 打赏
  • 举报
回复
引用 12 楼 zyq654321 的回复:
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述
初学或者没太大项目经验时,注入的优点确实很难体会出来。项目不大时、没有什么需求变化之类时,用注入也感觉不到什么优势,还不如直接 new 一个对象方便。 并且注入的方便并不体现在编写代码上,本人体验是对模块之间的解耦,也是所谓的面向接口编程思想的实现 这样说过于抽象了,简单举个例子: 你的部门需要一个Linux工程师来完成某个项目,于是部门老大向人力资源部提一堆要求,需要拿过什么证,有什么经验,精通XX、YYY等,需要这个人花20天时间解决某某问题。你可以认为些要求是接口,你们定义了一个接口规范,规范的要求就是人力资源要求。然后HR帮你找人,公司里别的部门可能正好有符合你要求的人,他正在闲置,所以把人派给你,如果没有,他们可能到人才网招聘,或者从人力派遣公司借调……,HR找到人之后,把人派给你们部门,工作时你不必关心他是哪来的,只要他是符合接口规范、能完成你的部门要求就的就行了。你可以把HR派人给你的操作当作注入。当他的工作完成之后,HR会安排他的去处,可能回到原部门,可能被辞退……这不是你的部门要关注的事,这是HR要做的事。在这里,你可以把HR当作框架,他们负责注入对象的生命周期管理。 拿项目说事的话呢,比如有个算滞纳金的模块,参数就是本金、开始计算日期,当前日期(取系统日期)。但是算法有很多讲究,比如要不要跳过节假日,周六、周日算不算节假日,滞纳金总金额最高不能超过本金的多少倍等等。不同的客户要求不相同,你的一个软件要满足多个客户要求,要部署到多个服务器上,每台服务器上的计算逻辑各不相同。当然你可以设置参数,不过用注入的方式,可以把滞纳金计算逻辑定义成接口,然后由不同的类进行实现,部署时根据客户的不同注入不同的实现。
小灰狼 2021-01-26
  • 打赏
  • 举报
回复
注入的对象一般是接口类型,或者抽象类类型。因为是接口或者抽象类,所以真正运行的时候给你的是哪个实现,可以由配置或者注解来决定,你在项目里要做的就是根据接口提供的功能把你的业务逻辑处理好。 这就好比你要装修一套房子时,准备好家里用的宽带、电、燃气的接口,你可以在家里放好电脑、网络电视,各种电器还有燃气灶、燃气热水器,真正准备搬进去住的时候,宽带你可以选择电信、移动或者联通,或者二道贩子(象什么长城宽带之类的),用电、用气之类的手续办好…… 比如你开始用的长城宽带,后来觉得不好,你可以换移动的,这就相当于是重新注入了一个接口对象。可能影响你的体验,但功能它们应该是一样的。 当然这是理想情况,实际开发时,往往为了方便会在一定程度上打破这种理想情况。 注入对象的生命周期,是由运行时的环境来进行管理的。什么时候创建,什么时候销毁,以及其它的一些资源管理,是由框架进行管理的,处理逻辑时不必过份操心。 又是当然,作为一个软件工程师,框架对这些注入对象的生命周期的管理机制,是应该要整明白的,不能一无所知!否则遇到某些特殊一点的用法,你会毫无办法,找不到出路!
老王就是我 2021-01-26
  • 打赏
  • 举报
回复
引用 12 楼 zyq654321 的回复:
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述
注入是使用对象,使用对象的形式为变量。如果还觉得无法理解,建议买本书研究下jvm的内存模型和gc
老王就是我 2021-01-26
  • 打赏
  • 举报
回复
引用 9 楼 zyq654321 的回复:
[quote=引用 8 楼 qybao的回复:]这是静态对象和非静态对象的区别,这种区别就不用多说了,跟注入毫无关系 至于为什么需要注入,那是因为可以让容器来帮你管理类而不需要自己手动去new(可以在一定程度上避免对象没有new而造成空指针错误,这样在一定程度上可以只关注逻辑而不用考虑如果对象没有初始化而带来的异常处理)
其实我发现我应该是想知道注入比new有啥优点,据说是注入只会申请一次内存,那static的类或者方法也只会申请一次内存[/quote] 注入通常用spring负责管理,如果用static,那么在操作dao的时候,需要写多少次jdbc连接串,要创建多少个对象?而注入是单例,只需创建一次对象,一个是创建多次一个是创建一次,哪个内存开销小?
qq_39936465 2021-01-26
  • 打赏
  • 举报
回复
引用 12 楼 zyq654321 的回复:
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述
注入的便利在于框架的使用,框架的配置文件就是一种注入,框架设计者已经帮你搭建好了,无需自己编写繁琐的程序,只需要把必要的数据写入配置文件就能让框架跑起来,这个是static无法实现的。
qybao 2021-01-26
  • 打赏
  • 举报
回复
引用 12 楼 zyq654321 的回复:
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述

好处或便利,要视项目而定,估计是LZ目前接触的项目用不到,等你用到了,你就能体会这个中的优缺点了
还是举个例子说明吧,你作为某个中间产品的提供商,提供的jar包里有如下两个类
一个提供处理逻辑可变的接口
interface IA {
void doSomething();
}

一个根据接口做相应处理的处理类
class PA {
//讨论使用注入和不使用注入的区别
IA a;
public void execute() {
a.doSomething(); //使用注入,代码可以很简洁,直接拿来就用,而且开发者不用关心 a 的生成细节
}
}


假设A,B两个用户都要使用你的jar包,他们分别是现实IA的接口
class AA implements IA {
public void doSomething() {
//do A business;
}
}
class AB implements IA {
public void doSomething() {
//do B business;
}
}

A只需要配置xml,让容器知道在IA a的地方,自动生成AA的实例(也就是注入的功能),那么PA可以不改动
同样的,B也只需要配置xml,让容器知道在IA a的地方,自动生成BB的实例,那么PA也可以不改动

那么好了,如果不用注入,PA会怎样?
首先,针对A和B实现类的不同,PA肯定要改,否则就不能对应业务了,那么PA怎么改?
class PA {
IA a;
public void execute() {
//要根据不同需求自己生成a实例,怎么根据需求来分?假设用个配置文件properties
try {
String clz = System.getProperty("IA的实现类"); //A和B用户只需要配置properties文件
a = (IA) Class.forName(clz).getDeclaredConstructor().newInstance(new Object[] {"参数(假设有参数的话)"});
} catch (Exception e) {
e.printStackTrace();
}
a.doSomething();
}
}


你会觉得,其实也没多复杂,没体现出注入的好处,也就多几行代码而已?
是这样吗?例子简单那是因为关系简单,如果PA需要的不只是IA接口,还有很多其他接口,那么这部分的代码量就会增加,维护成本就会上升。
其次,如果a实例的属性也是多变的,那么你的new instance的参数部分又要花一部分精力的考虑怎么动态创建管理参数,代码复杂读增大
而且每增加,修改或删除一个属性,比如PA多加一个IAX的属性,那么代码改动量也不少,影响范围比较大。
同样的a属性发生增加,修改或删除,你的new instance的参数部分的处理,影响范围也不小。
项目小的时候,这些问题都好管理,等项目越做越大,越做越复杂的时候,你就会发现这是个灾难。
当然如果你很自负,觉得这一切都不是问题,那也没什么好说的了,但是至少,你应该可以发现,用了注入能可以在一定程度上避免一些问题。
在这追求高速高效开发的时代,你还愿意自己闭门造车轮吗?

maradona1984 2021-01-25
  • 打赏
  • 举报
回复
引用 12 楼 zyq654321 的回复:
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述
楼上已经说了很多了,如果还不理解的话,建议去学习下设计模式. 仅仅是注入来说,接口的话,你可以有很多实现,这就相当于面向接口编程,但大多数接口是没有多个实现类的,所以你感觉不到他在这方面的好处. 还有注入的对象是spring替你做的,所以他能非常方便的实现aop,spring给你留了很多钩子去做扩展,这也算是好处之一,如果你自己new,那就相当复杂了.
zyq654321 2021-01-24
  • 打赏
  • 举报
回复
我怎么没有感受到注入能带来啥好处或者便利,不理解,希望高手指点,最好用简单的语言描述
八爻老骥 2021-01-20
  • 打赏
  • 举报
回复
引用 9 楼 zyq654321 的回复:
[quote=引用 8 楼 qybao的回复:]这是静态对象和非静态对象的区别,这种区别就不用多说了,跟注入毫无关系
至于为什么需要注入,那是因为可以让容器来帮你管理类而不需要自己手动去new(可以在一定程度上避免对象没有new而造成空指针错误,这样在一定程度上可以只关注逻辑而不用考虑如果对象没有初始化而带来的异常处理)

其实我发现我应该是想知道注入比new有啥优点,据说是注入只会申请一次内存,那static的类或者方法也只会申请一次内存[/quote]

IOC的目的是为了在一定的生命周期内,缓存某些领域对象(比如数据库连接、Dao、Service,Web服务代理对象,Ejb的客户端等),以减少因高频的new带来的系统开销,依赖注入是其衍生的功能,使用注入可以避免在引用缓存对象时,将IOC上下文硬编码到业务代码中。当然,在业务类中属性使用接口而不是具体类型,可以进一步降低代码的偶和性,都是些小技巧方面的东西。
qybao 2021-01-20
  • 打赏
  • 举报
回复
注入只申请一次内存,那是因为容器默认使用单实例管理,修改配置改成多实例管理就不只一次申请内存了。 至于注入有什么优点,那就看开发者的需求了。注入是把对象的依赖管理交给容器,开发中可以避开一些繁琐的对象初始化处理(交给容器负责),开发者只需要关注自己的业务逻辑,从容器中拿来就用,能缩短开发时间。 当然,任何事物都是两面性的,注入也有相应的限制,失去一定的开发自由。 就好比框架一样,框架是帮你把整个mvc流程管理好,开发者只需按照框架的规则开发业务逻辑。不使用框架可不可以?那当然可以,只是会增加开发工数和开发复杂度。同样的,注入也是同样的道理。
一个帅逼 2021-01-19
  • 打赏
  • 举报
回复
就说一点吧,srping管理的bean是代理类
maradona1984 2021-01-19
  • 打赏
  • 举报
回复
引用 2 楼 叫练 的回复:
你是说Java注入随时可以用是说的Java代码中spring的注解如@Autowire,当spring框架初始化会解析注解,实例化这些注解对象,对象默认是一个单例,你可以理解成一个大的hashmap,key是属性名,val是实例对象。 你说的static随时可以用她不叫static方法,叫static静态代码块,当类初始化会自动加载静态代码块。spring注解和static本质上都是初始化代码,没有区别。希望对你有帮助
静态方法和普通方法的区别就在于面向对象上的区别,初始化只是一个功能而已,完全不能拿到设计这个层次来讲.
maradona1984 2021-01-19
  • 打赏
  • 举报
回复
学java的第一天接受的概念就是java面向对象三大特性,封装、继承、多态,静态方法的句柄是类,面向对象的特性他都没有,注入的是对象,所以这些注入拥有面向对象的特性. 你的问题可以简化成静态方法和普通方法的区别,找到事物的矛盾点是学习能力的重要体现,注入这个表象迷惑了你罢了.
叫练 2021-01-19
  • 打赏
  • 举报
回复
你是说Java注入随时可以用是说的Java代码中spring的注解如@Autowire,当spring框架初始化会解析注解,实例化这些注解对象,对象默认是一个单例,你可以理解成一个大的hashmap,key是属性名,val是实例对象。 你说的static随时可以用她不叫static方法,叫static静态代码块,当类初始化会自动加载静态代码块。spring注解和static本质上都是初始化代码,没有区别。希望对你有帮助
qq_39936465 2021-01-19
  • 打赏
  • 举报
回复
引用 楼主 zyq654321 的回复:
都是随时可以用,费那么大劲搞注入,怎么也想不明白,那位大神能用简单的语言解释一下,或者转发一些文章也可以
静态的只能用静态不能调用非静态,注入的话没有这个限制。
加载更多回复(3)

67,515

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧