关于Java重载方法时的可用修饰符
来源:互联网 发布:淘宝上怎么开店流程图 编辑:程序博客网 时间:2024/06/05 16:19
一、final在重载参数的可用性
之前在写代码的时候,在一个重载方法里由于用到里Runnable匿名类,需要对参数进行final指定,由于基类的参数都没有final修饰符,基类的函数原型如下:
public abstract void write(char[] buf, int offset, int count) throws IOException;
所以打算在内部重新声明final变量来赋值,即
@Overridepublic void write(char[] buf, int offset, int count) throws IOException {final char[] writeBuf = buf;}
不过尝试之下,发现可以直接在重载方法上添加final,即使基类的方法里的参数没有声明final,即
@Overridepublic void write(final char[] buf, int offset, int count) throws IOException {}
编译可以通过。
二、具体原因
后来在stackoverflow查找相关原因的时候,发现以下解释:
According to the Java Language Specification 4.12.4:
Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.
However, a final
modifier on a method parameter is not mentioned in the rules for matching signatures of overridden methods, and it has no effect on the caller, only within the body of an implementation.
具体来说,其实由于final修饰符只在当前实现函数中起作用,只是对编译器的一种提示,不会出现具体的.class文件中,而且无论参数是否final,java都只会进行pass by value的传参形式。说到底,final只是代表当前重载函数的具体实现,与接口无关,因此JSE规范里没有把这个列入函数签名中,属于具体实现细节。
三、其他可用修饰
这里稍微延伸一下,对于相同原理的还有synchronized关键字:
@Overridepublic synchronized void write(final char[] buf, int offset, int count) throws IOException {}
即在重载函数里添加synchronized关键字同样是允许的,因为与final意义一样,是当前函数的具体实现,不影响接口声明。
至于对于声明里的异常抛出,则有不同规则,因为这会导致接口的实现的。
具体例子如下:
@Overridepublic synchronized void write(final char[] buf, int offset, int count) throws JSONException {}
上面这个例子会导致编译失败,具体由于抛出里JSONException,比基类多抛出一个已经检查的异常。
@Overridepublic synchronized void write(final char[] buf, int offset, int count) {}有趣的是,上面这个例子编译可以通过,虽然比基类少声明里一个已经检查的异常。
不过这样做的确是合理的,因为实现接口的函数必然不能有比接口多的异常,否则会影响接口的使用。
另外还有对于修饰符不能低于接口的权限等等,也即接口是protected,实现函数就必须是protected以上的权限修饰。
四、详细资料
具体可以参考JSE的关于重载函数的要求:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.8.3
以及函数签名的解释:
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.2
- 关于Java重载方法时的可用修饰符
- Java构造方法、重载、访问修饰符
- Java知识(访问修饰符、方法重写和方法重载的区别以及java抽象)
- 关于JAVA的修饰符
- java :引用类型的转换 方法重载和重写 构造函数 修饰符
- 类,方法,成员变量,局部变量的可用修饰符
- 关于java注释,修饰--方法
- 关于Java的方法的重载
- java中的void修饰的方法,方法重载,方法参数传递问题
- 关于JAVA中方法的重载
- 关于java方法重载的理解
- 类、对象、继承、封装、多态、方法的重载和重写、Java的访问修饰符与其它关键字
- Java学习笔记-修饰符可修饰的属性方法
- 关于Java修饰符的一些练习题
- 摘抄别人:关于java的修饰符
- 关于Java的访问控制修饰符
- 关于Java的访问控制修饰符
- JAVA中关于修饰符的使用
- PAT A 1027. Colors in Mars (20)
- C/C++中调用LUA函数
- 还原TexturePacker plist 文件以及图片的方法 (切开各小图片)
- Word Break
- 求int型a,b,c三个数中的最大数
- 关于Java重载方法时的可用修饰符
- Lua脚本在C++下的舞步(三)
- Apache+PHP+Mysql OS X 10.9 Mavericks WEB 服务器配置
- 由Q_OBJECT引起的undefined reference to vtable for "xxx::xxx"问题
- dom4j对xml进行读写操作
- Ubuntu下Aircrack-ng工具包的使用
- NGUI 3.5教程(一)安装NGUI 3.5.8
- POJ 3620 Avoid The Lakes(简单DFS求连通分量)
- 动态规划