三。java中有final
final 修饰符 关键字可用于修饰类,变量和方法,final关键字有点类似于C#里的sealed 关键字,用于表示它修饰的类,方法和变量不可改变。
fina修饰变量时,表示该 变量一旦获得了初始值就不可被改变,final既可以修饰成员变量,也可以修饰局部变量,形参。严格的说法是:final修饰的变量不可被改变,一旦获得了初始值,该final变量的值就不能被重新赋值。
 
final成员变量,成员变量是随类初始化或对象初始化而初始化的,当类初始化时,系统会为该类的类变量分配内存,并分配默认值,当创建对象时,系统会为该 对象的实例变量分配内存,并分配默认值。也就是说,当执行静态初始化块时可以对类变量赋初始值,当执行普通初始化块,构造哭喊时可对实例变量赋初始值。因此成员变量的初始值可以在定义该变量时指定默认值,也可以在初始化块,构造器中指定初始值。
    对于final修饰的成员变量而言,一量有了初始值,就不能被重新赋值,如果既没有在定义成员变量时指定初始值,也没有在初始化块,构造器中为成员变量指定初始值,那么这些成员变量的值将一直是系统默认分配的0 \u0000 false null
 
归纳final修饰的类变量,实例变量能指定初始值的地方如下:
  类变量必须在静态初始化块中指定初始值或声明该类变量时指定初始值,而且只能在两个地方的其中之一指定。
  实例变量必须在非静态初始化块,声明该变量或构造器中指定初始值,而且只能在三个地方其中之一指定。
final 修饰的实例变量,要么在定义该实例变量时指定初始值,要么在普通初始化块或构造器中为该 实例变量指定初始化值,但需要注意的是,如果普通初始化块已经为某个实例变量指定了初始值,则不能再在构造器中为该 实例变量指定初始值:final修饰的类变量,要么在定义该 类变量时指定初始值,要么在静态初始化块中为该类变量指定初始值。
实例变量不能在静态初始化块中指定初始值因为静态初始化块是静态成员,不可能访问实例变量 --非静态成员;
类变量不能在变通初始化块中指定初始值,因为类变量在类初始化阶段已经被初始化了,普通初始化块不能对其重新赋值。
public class FinalVariableTest
{
    //定义成员变量时指定默认值 合法
    final int a=6;
    //下面变量将在构造器或初始化块中分配初始值
    final String str;
    final int c;
    final static double d;
    //既没有指定默认值,又没有在初始化块,构造器中指定初始值
    //下面定义的ch实例变量是不合法的
    //fianl char ch;
    //初始化块,可对没有指定默认指定默认值的实例变量指定初始值
    {
        str="Hello";
        //定义a实例变量时已经指定了默认值
        //不能为a重新赋值,因此下面赋值语句非法
        //a=9
    }
    //静态初始化块,可对没有指定默认值的类变量指定初始值
    static
    {
        //在静态初始化块中为类变量指定初始值,合法
        d=5.6;
    }
    //构造器,可对既没有指定默认值,又没有在初始化块中指定初始值的实例变量指定初始值
    public FinalVariableTest()
        {
        //如果在初始化块中已经对str指定了初始值
        //那么在构造器中不能对final变量重新赋值,下面赋值语句非法
        //str="java";
        c=5;
    }
    public void changeFinal()
    {
        //普通方法不能为fianl修饰的成员变量赋值
        //d=1.2
        //不能在普通方法中为fianl成员变量指定初始值
        //ch='a';
    }
    public static void main(String[] srgs)
    {
        FinalVariableTest ft=new FinalVariableTest();
        System.out.println(ft.a);
        System.out.println(ft.c);
        System.out.println(ft.d);
    }
}
 
系统不会对fianl成员变量进行初始化,
系统不会对局部变量进行初始化,局部变量必须由程序员显式初始化。因此使用final修饰局部变量时,既可以在定义时指定默认值,也可以不指定默认值。
 如果final修饰的局部变量在定义时没有指定默认值,则可以在后面代码中对该 final变量赋初始值,但只能一次,不能重复赋值;如果final修饰的局部变量在定义时已经指定默认值,则后面代码中不能再对该变量赋值。
 
final 修饰基本类型变量和引用类型变量的区别
    当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变。
但对于引用类型变量而言,它保存的仅仅是一个引用,final只保证这个引用类型变量所引用的地址不会改变,即一直引用同一个对象,但这个对象完全可以发生改变。
 
 
 
 
可执行“宏替换”的final变量
对一个fianl变量来说,不管它是类变量,实例变量,还是局部变量,只要该变量满足三个条件,这个final变量就不再是一个变量,而是相当于一个直接量。
  一:使用final修饰符修饰;
 二:在定义该final变量时指定了初始值。
 三:该初始值可以在编译时就被确定下来。
如下:
public class FinalLocalTest
{
    public static void main(String[] args)
    {
    final int a=5;
    System.out.println(a);
    }
}
 
 
final 方法
    final 修改的方法不可被重写,如果出于某些原因,不希望任何类重写这个方法,所以使用final把这个方法密封起来。但对于该类提供的toString()和equals()方法,都允许子重写,因此没有使用final修饰它们。
如下会引起编译错误:
 
 
public class finalMethodTest
{
public final void test(){}
}
class Sub extends FinalMethodTest
{
public void test (){};
}
 
 
上面的程序 中父类是FinalMethodTest,该类里定义的test方法是一个fianl方法,如果其子类试图重写该方法,将会引发编译错误。
对于一个private 方法,因为它公在当前类中可见,其子类无法访问该方法,所以子类无法重写该方法--如果子类中定义一个与父类private 方法有相同方法名,相同参数列表,相同返回值类型的方法,也不是方法重写,只是重新定义了一个新方法,因此,即使使用final修饰一个private 访问权限的方法,依然可以在其子类中定义与该 方法具有相同方法名,相同参数列表,相同返回值类型的方法。
 
 
如下:
 
 
public class finalMethodTest
{
    privete final void test(){}
}
class Sub extends FinalMethodTest
{
    public void test (){};
}
final 类:
final 修饰的类不可以有子类,例如java.lang.Math类就是一个final类,它不可以有子类。
    当子类继承父类时,将可以访问到父类内部数据,并可通过重写父类方法来改变父类方法的实现细节,这可能导致一些不安全的因素。为了保证某个类不可被继承,则可以使用final修饰这个类。下面代码示范了final修饰的类不可被继承。
 
public final claa FianlClass{}
class Sub extends FinalClass{};
这样会出现编译错误。

java 中的fanal的更多相关文章

  1. java中的锁

    java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...

  2. java中的字符串相关知识整理

    字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...

  3. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  4. java中Action层、Service层和Dao层的功能区分

    Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...

  5. Java中常用集合操作

    一.Map 名值对存储的. 常用派生类HashMap类 添加: put(key,value)往集合里添加数据 删除: clear()删除所有 remove(key)清除单个,根据k来找 获取: siz ...

  6. java中的移位运算符:<<,>>,>>>总结

    java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     右移运算符,num >& ...

  7. 关于Java中进程和线程的详解

    一.进程:是程序的一次动态执行,它对应着从代码加载,执行至执行完毕的一个完整的过程,是一个动态的实体,它有自己的生命 周期.它因创建而产生,因调度而运行,因等待资源或事件而被处于等待状态,因完成任务而 ...

  8. Java中的进程和线程

     Java中的进程与线程 一:进程与线程 概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是 ...

  9. Java中的进程与线程(总结篇)

    详细文档: Java中的进程与线程.rar 474KB 1/7/2017 6:21:15 PM 概述: 几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程.当一个进 ...

随机推荐

  1. Filezilla Server 配置大全

    一个开源.免费的FTP服务端程序,Windows 安装程序(0.9.50 beta):右键另存为. 首先说一下FTP的二种模式:主动模式(port mode)与被动模式(passive mode),网 ...

  2. item31,连续子数组的最大和

    整型数组,元素有正数和负数.数组中一个或连续的多个整数组成一个子数组,求所有子数组中最大值. =========== 动态规划, 状态转移方程,max[].size = nums.size() max ...

  3. VMWare虚拟机下RedHat 9.0linux的网络设置

    VMWare虚拟机下安装的RedHat 9.0 linux有三种方式实现上网,桥接.nat.host-only.本来想用桥接方式的,可总是因为配置网络出现问题而不能上网,还把 sygate4.5(代理 ...

  4. UNIX网络编程

    UNIX网络编程--socket的keep http://www.68idc.cn/help/opersys/unixbsd/20150731471448.html

  5. linux shell 中的位置变量

    对于linux shell 中的位置变量,我一直以来都是吐不出来又咽不下去,每次看到都不懂,不懂了就去百度google,看完了又忘,真是慢性咽炎啊.现在认真想想也是,其实自己一直以来都没有好好学习过, ...

  6. 标准电流信号为什么是4-20MA?(网络摘录)

    一来源: 4-20mA.DC(1-5V.DC)信号制是国际电工委员会(IEC):过程控制系统(是连接仪表.变送设备.控制设备.计算机采样设备)用模拟信号标准.我国从DDZ-Ⅲ型电动仪表开始采用这一国际 ...

  7. systick优先级的理解

    sysTick系统嘀嗒定时器并非STM32独有的,它是Cortex内核的部分,CM3为它专门开出一个异常类型,并且在中断向量表中占有一席之地(异常号15).这样它可以很方便的移植到不同厂商出CM3内核 ...

  8. ylbtech-LanguageSamples-XMLdoc

    ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-XMLdoc 1.A,示例(Sample) 返回顶部 “XML 文档”示例 本示例演示如 ...

  9. 如何开启ubuntu的SSH服务(不要和openssl搞混淆了)

    ubuntu默认并没有安装ssh服务,如果通过ssh链接ubuntu,需要自己手动安装ssh-server,然而SSH分客户端openssh-client和服务端openssh-server,open ...

  10. H2 database的使用

    H2最完整的资料下载地址: http://download.csdn.net/detail/yixiaoping/5956595       H2数据库使用   H2数据库介绍 常用的开源数据库:H2 ...