浅谈java中注解和python中装饰器的区别
⽂章⽬录
写在前⾯
结论,直接看 5、总结
写这篇⽂章之前,我先百度了⼀下⽹上的答案,发现⼤多数⽂章⽤了类似的解释,如下:
Java 注解也叫元数据,⼀种代码级别的说明。Python 装饰器是⼀种语法糖。
注解是给别⼈看的,功能不仅仅由注解决定;装饰器直接拦截,直接改变被装饰对象的⾏为!
注解(Annotation):仅提供附加元数据⽀持,并不能实现任何操作。需要另外的 Scanner 根据元数据执⾏相应操作。
装饰器(Decorator):仅提供定义劫持,能够对类及其⽅法的定义并没有提供任何附加元数据的功能。
看起来 注解和装饰器 完全在两个不同的⽅向作⽤,但真的是这样吗?
以下仅为个⼈见解,欢迎⼤佬批评指正
1、望⽂⽣义
注解: 注释?解释?标注? 像注释⼀样,⽤来解释代码的?
装饰器: 装修?修饰? 让函数更好看?
2、写法异同点
@aaa(“abc”)
相同点:都是@开头,注解、装饰器都可以⾃定义、都可以带参数、都可以被标注代码块之前执⾏。
不同点: java注解可以写在类、⽅法、变量头上,python装饰器可以写在类、⽅法头上。
3、在实例中对⽐
下⾯对注解和装饰器分别举例,对⽐其区别
3.1、java注解
@Override
public String toString(){
return"Teacher{"+
"id="+ id +
", name='"+ name +'\''+
", users="+ users +
'}';
}
@Override 的作⽤是标记重写⽅法,在编译阶段对⽅法进⾏检查。
从这个例⼦中我们发现注解作⽤在了对⽅法的编译、检查上,并未对⽅法的内容和功能发⽣改变。
3.2、python装饰器
class A():
java python是什么意思
@property
def bb(self):
return self.value
if __name__=="__main__":
A.bb =9
print A.bb
@property 的作⽤是将函数bb,做为属性使⽤
从这个例⼦中我们发现装饰器能够直接改变函数的功能。
3.3、简单总结
如上两个简单的例⼦,我们简单总结出注解和装饰器不⼀样的地⽅
1、注解对元数据进⾏了检查、对⽐等⼯作,不会对所修饰的代码产⽣直接的影响。
2、装饰器可以对⽅法进⾏功能上的改变,可以对所修饰的代码产⽣直接的影响。
到这⾥,你也许会觉得 装饰器和注解 ⾛的路线完全不同了,其实不然,在java中注解+反射能够实现和python⾥装饰器同样的效果。
4、更多实例对⽐
4.1、注解
1、在mybatis中使⽤注解传递sql
(这⾥并不能直接给getUsers传参数,⽽是利⽤了另⼀个类反射注解的参数,然后传值给getUsers)
2、@Test标记该⽅法为测试⽅法
4.2、装饰器
1、⽇志打印器
2、计算运⾏时间
5、总结
第⼀点:对代码块的影响
java注解:不会对所修饰的代码产⽣直接的影响。
python装饰器:可以对所修饰的代码产⽣直接的影响。
第⼆点:共通处
java中注解+反射 可以实现 python装饰器同样的功能,包括⾯向切⾯编程、参数校验等。
第三点:从⽤途看
从⽤途看注解像是注释⽂档⼀样,⽤于⽣成javadoc⽂档(以参数形式标注)、检查等。
装饰器像是为函数提供更多的功能,并装在不同的函数⾝上。
第四点:从原理看
java注解:所有注解本质是继承⾃接⼝(Annotation)的接⼝
我们看⼀个 JDK 内置注解的定义:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
这是注解@Override的定义,其实它本质上就是:
public interface Override extends Annotation{
}
python装饰器:被装饰函数的返回值 作为参数传给闭包函数执⾏(这个闭包函数名前⾯加个@,就是装饰器)说⽩了装饰器就是⼀个闭包函数。
下⾯是⼀个闭包函数的实例
def outer(x):
def inner():# 函数嵌套
return x                  # 跨域访问,引⽤了外部变量x
return inner                  # 函数作为返回值
closure = outer('外部变量')# 函数作为变量赋给closure
print(closure())# 执⾏闭包
#结果
外部变量
下⾯是⼀个装饰器实例
def outer(x):
def inner():
return'戴了inner牌帽⼦的 '+ x()
return inner
@outer
def func():
return'函数func'
print(func())
#结果
戴了inner牌帽⼦的函数func
6、闲谈⼀下
在写这篇⽂章时查阅了部分资料和⽹上的⽂章,
每个⼈有⾃⼰不同的看法,
刚看见这个两种语法的时候,发现它两都是标在别⼈头上嘛,
研究到它两各⾃的原理后,这两家伙完全就不是⼀路⼈。
⼀个标注在别⼈头上,仅仅是给别⼈打标签,别的什么都⼲不了。
另⼀个标注在别⼈头上,可以指挥函数的任何功能。
学到后⾯,开始接触它两的实际应⽤后,
发现它两很多时候都被⽤来校验参数、增加功能、减少代码重复、⾯向切⾯等。
所以殊途同归,
打开注解源码,⾥⾯仅记录了⼀些变量、默认值等,但它借助反射、封装等实现了功能。打开装饰器源码,⾥⾯是⼀个闭包函数,功能由它⾃⼰实现。最终他们都被⽤来完成了同样的⼀些功能和效果。
使⽤注解(Annotation)的语⾔:AtScript、Java、C#(叫 Attribute)。
使⽤装饰器(Decorator)的语⾔:Python、JavaScript/ECMAScript。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。