zoukankan      html  css  js  c++  java
  • JAVA——不简单的fianl关键字

    protected
    用来修饰 域,代表域的访问权限是:包权限 或者 不同包,但是是子类 ;

    final 修饰常量
    只要是该常量代入的计算式,在编译时期,就会被执行计算,以减轻运行时的负担。(只对基本数据类型的计算式,奏效)

    final 修饰引用
    这个有个地方需要说下,只是引用指向的对象,一经确定,就不再可以修改为指向别的对象。但是对象本身的属性,可以随意改变;

    空白 final
    就是被申明为final,但是未赋值的域 ,称为 空白final ;但是在使用之前,必须对其进行赋值;
    这样就可以灵活的为其进行赋值,但是又保持了其不可更改的特性 ;

    final 参数
    就是方法参数,被final修饰了;跟final引用一样,无法更改其指向其他对象 ;

    final 方法
    被修饰的方法,只能被继承,但是不能被覆盖 ;被修饰为final的方法,其实是用了前期绑定,因此,在之前这样做是可以提升效率的;

    final 类
    final类不可被继承,final类的方法,都被隐式的设定为final,但是域,不是final的,可以根据自己的意愿来设定 ;

    子父类中同名的 private 方法
    public class test {
    public static void main(String[] args) {
    A a = new B();
    a.haha(); ; // error
    a.hehe(); ; // ok
    }
    }
    class A{
    private void haha(){
    System.out.println(“A”);
    }

    public void hehe(){
    System.out.println("A");
    }
    1
    2
    3
    }

    class B extends A{
    private void haha(){
    System.out.println(“B”);
    }
    }

    它们之间是没有任何关系的;只是恰巧重名了 ;它们不能发生多态的行为;

    方法的覆盖和向上转型,只针对方法是父类中能被子类继承的方法 ;因此,它们之间是没有向上转型、覆盖的说法的,也就没有多态的行为;

    java中的前期绑定
    我们都知道,java是采用后期绑定的;

    但是,其实在java中有的地方,也采用可前期绑定;比如:static方法、final方法;这两种方法是前期绑定的;

    由于private是隐式的final方法,因此,private方法也是前期绑定哦;

    对了 构造器也是前期绑定,因为,其实,那个构造器是隐式的static方法 ;

    免疫多态
    域 和 静态方法 是不会产生多态行为的 ;

    任何对 域 的操作,都是在 编译时期 完成的,此时编译器认为父类引用的就是父类的对象,因此,根本不存在多态的可行性;

    静态方法,不存在多态的原因是:静态方法 是 前期绑定,此时编译器,也是单纯的认为,父类引用指向的就是父类对象,天真!

    对于它们,是 编译看左边,运行看左边;

    class A {

    public int a = 1 ;
    private void haha(){
    System.out.println("A");
    }

    public void hehe(){
    System.out.println("A");
    }

    public static void aa(){
    System.out.println("aa");

    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    }

    class B extends A{
    public int a = 2 ;
    private void haha(){
    System.out.println(“B”);
    }

    public static void aa(){
    System.out.println("bb");

    }
    1
    2
    3
    4
    }

    public class test {
    public static void main(String[] args) {
    A a = new B();
    System.out.println(a.a);
    a.aa();
    }
    }

    // output:1 aa ;都是输出父类的。

    谁先被执行,构造器 还是 初始化?
    从代码上看会有误解,先执行了构造器的第一句代码 ;其实,从虚拟机的层次讲,是先执行初始化的,后执行构造器;这涉及到类加载器对类进行加载的时候,会把类的信息,加载进方法区,虚拟机在查看类的类型信息的时候,如果发现有父类,则继续去加载父类的类文件,如果没有父类了,则开始初始化类,再然后执行构造器;然后一层一层的返回,这是从虚拟机层次看的;

    但是,从代码层次看,给我们的感觉,则是先执行构造器,进行判断,看第一句代码是否有隐式的调用父类构造器,如果是,则跳转到父类构造器中,继续执行此逻辑 ;直到没有父类了,然后进行初始化,初始化完成以后,继续执行构造器中剩下的代码 ;

    协变返回类型
    在JDK1.5以后,在子类覆盖的方法,子类方法的返回值类型 可以是父类该方法返回值的子类 ;

  • 相关阅读:
    【知识强化】第四章 网络层 4.1 网络层的功能
    【知识强化】第三章 数据链路层 3.8 数据链路层设备
    【知识强化】第三章 数据链路层 3.7 广域网
    【知识强化】第三章 数据链路层 3.6 局域网
    【知识强化】第三章 数据链路层 3.5 介质访问控制
    【知识强化】第三章 数据链路层 3.4 流量控制与可靠传输机制
    ASP.NET MVC入门之再不学习就真的out了
    ASP.NET MVC系列:添加模型的验证规则
    ASP.NET MVC系列:为已有模型添加新的属性
    ASP.NET MVC系列:为视图添加查询功能
  • 原文地址:https://www.cnblogs.com/hyhy904/p/10961991.html
Copyright © 2011-2022 走看看