JAVA之private修饰成员方法默认是final型的?

x33g5p2x  于2022-01-04 转载在 Java  
字(1.9k)|赞(0)|评价(0)|浏览(375)

Java之private修饰成员方法默认是final型的?

private修饰的成员方法默认final型的?

  • 用fianl声明的成员方法是最终方法,最终方法不能被子类覆盖(重写)

从表面上看这个命题是错误的,private访问修饰符修饰的成员方法怎么会跟final型方法有关系呢?但从最终方法的定义可以看出,不能被子类覆盖的成员方法就是最终方法,而private修饰的成员方法就不能被子类覆盖,证明如下:

  1. //证明private修饰的成员方法不能被子类覆盖
  2. class Father{
  3. int m = 0;
  4. private void set() {
  5. m += 1;
  6. }
  7. public Father() {
  8. set();
  9. }
  10. }
  11. public class Son extends Father{
  12. private void set() {
  13. m += 3;
  14. }
  15. public static void main(String[] args) {
  16. Father f = new Son();
  17. System.out.println(f.m);
  18. }
  19. }

输出:3

分析:
如果private修饰的set()方法被子类重写了,当执行到 Father f = new Son(); 语句,先执行Father类的构造方法,而构造方法的set()方法会调用子类的set()方法(多态的一种表现),输出结果为:1
而实际输出的结果为:3,因此private修饰的成员方法没有被子类覆盖,也就是说private修饰的成员方法默认是final型的。

  • 在class文件中,有专门描述方法的方法表,方法表第一项就是访问标志access_flags。其中标志值为0x0001的 ACC_PRIVATE代表方法为private;标志值为0x0002的 ACC_PUBLIC代表方法为方法为final,可以通过判断access_flags的值判断方法有哪些访问标志。
  1. public class Test {
  2. private void test(){}
  3. private final void test2(){}
  4. }

通过jclasslib bytecode viewer看出,如下图:

分析:
两个方法一个是只有private修饰,另一个是有private和final 修饰,如果private修饰的成员方法默认是final型的,那两个方法的access_flags值应该一样的,可结果并非如此,由此可以说明private修饰的成员方法默认是final型的是错误的。

如何理解 :类中所有的private方法都隐式的指定为是final的 为什么这么说?有理论依据么

正解,这段话来自《Java编程思想》多态那一章节,的确不太明白作者为什么要这样子去说。
这种说法完全没有根据,属于误人子弟 private和final没关系,是两回事 拿属性来说可能更容易理解一些,虽然private不能访问,但通过反射修改访问权限还是可以访问修改的,但加了final,即使可以访问了也修改不了值,这就是区别 自己用反射打印一下结果就知道了,或者用javap反编译看一下伪代码

  1. public class Sample {
  2. static class ATest {
  3. private void test1() {}
  4. private final void test2() {}
  5. }
  6. public static void main(String[] args) {
  7. try {
  8. Class<?> c = Sample.ATest.class;
  9. Method f1 = c.getDeclaredMethod("test1", null);
  10. System.out.printf("%s:%d\n", f1.getName(), f1.getModifiers()); //private修饰
  11. Method f2 = c.getDeclaredMethod("test2", null);
  12. System.out.printf("%s:%d\n", f2.getName(), f2.getModifiers()); //private final修饰
  13. System.out.printf("private:%d\n", Modifier.PRIVATE); //private的修饰值
  14. System.out.printf("final:%d\n", Modifier.FINAL); //final的修饰值
  15. System.out.printf("private & final:%d\n", Modifier.PRIVATE|Modifier.FINAL); //private和final一起的修饰值
  16. } catch (Throwable e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }

相关文章

最新文章

更多