final变量:

  对于基本类型使用final:它就是一个常量,数值恒定不变

  对于对象引用使用final:使得引用恒定不变,一旦引用被初始化指向一个对象,就无法再把 它改为指向另一个对象。然而,对象自身却是可以被修改的,java并没有提供使任何对象恒定不变的途径。这一限制同样也使用数组,它也是对象。

例子:

class Value{
int i;
public Value(int i){
this.i = i;
}
} public class FinalData {
private static Random random = new Random(47);
private String id; public FinalData(String id){
this.id = id;
} private final int valueOne = 9;
private static final int VALUE_TWO = 99;
public static final int VALUE_THREE = 39;
private final int i4 = random.nextInt(20);
static final int INT_5 = random.nextInt(20); private Value v1 = new Value(11);
private final Value v2 = new Value(22);
private static final Value VAL_3 = new Value(33); private final int[] a = {1, 2, 3, 4, 5, 6};
public String toString(){
return id + ": " + "i4 = " + i4 + ", INT_5 = " + INT_5;
} public static void main(String[] args) {
FinalData fd1 = new FinalData("fd1");
//! fd1.valueOne++; // 因为valueOne是基本类型常量,其数值恒定不变
fd1.v2.i++; //final修饰的对象的内容可以改变
fd1.v1 = new Value(9);
for(int i = 0; i < fd1.a.length; i++)
fd1.a[i]++;
//! fd1.v2 = new Value(0); // 因为v2是final修饰的引用类型,其引用不能被修改指向另一个对象
//! fd1.VAL_3 = new Value(1); // 表示占据一段不能改变的内存空间
//! fd1.a = new int[3]; // final修饰的数组
System.out.println(fd1);
System.out.println("Creating new FinalData");
FinalData fd2 = new FinalData("fd2");
System.out.println(fd1);
System.out.println(fd2);
}
}
/*output:
fd1: i4 = 15, INT_5 = 18
Creating new FinalData
fd1: i4 = 15, INT_5 = 18
fd2: i4 = 13, INT_5 = 18
*/

分析:

  对于fd1,fd2两个对象,其中i4是唯一的,即每个对象都有一个i4,但INT_5被声明为static,即是类共享的,fd1和fd2共享INT_5,在装载时已经被初始化,而不是每次创建新对象时初始化(例如i4);但它同时被设置成final,所以它的引用是不可改变的,即不能被修改指向另一个对象。

空白final:

  被声明为final但又没有给定初值。必须在域的定义或者每个构造器中使用表达式对final进行赋值,这正是final域在使用前总是初始化的原因。

final参数:

  这意味着你无法在方法中更改参数引用,使其指向另一个参数,但可以修改final对象所指向的内容

例子:

class Gizmo{
int i = 0;
public void spin(){}
} public class FinalArguments {
void with(final Gizmo g){
//! g = new Gizmo(); // 无法修改final修饰的引用,使它指向另一个对象
g.i++; // 但可以修改final对象所指向的内容
}
void without(Gizmo g){
g = new Gizmo();
g.spin();
} // int g(final int i){
// //! i++; //因为参数i是常量值
// } int g(final int i){
return i + 1;
} public static void main(String[] args) {
FinalArguments bf = new FinalArguments();
bf.without(null);
bf.with(null);
}
}

分析:

  参数被声明为final,若是基本参数,那它就是一个常量,不能被修改;若是一个引用变量,那么它就不能被修改指向另一个对象,但可以修改该引用所指对象的内容。

fianl方法:

使用原因:

  1. 把方法锁定,以防任何继承类修改它的含义,即该方法不会被继承的类覆盖
  2. 效率,若一个方法指明为final,那么就同意编译器将针对该方法的所有调用转为内嵌调用。

类中所有的private方法都隐式地指定为final,由于无法取用private方法,所以也就无法覆盖它。可以对private方法添加final修饰词,但这并不会给该方法带来任何额外的意义。

例子:

class WithFinals{
private final void f(){
System.out.println("WithFinals.f()");
}
private void g(){
System.out.println("OverridingPrivate.f()");
}
} class OverridingPrivate extends WithFinals{
private final void f(){
System.out.println("OverridingPrivate.f()");
}
private void g(){
System.out.println("OverridingPrivate.g()");
}
} class OverridingPrivate2 extends OverridingPrivate{
/*
* 当使用Override注解强制使f()方法覆盖父类的f()方法时,会报错
* 因为它不知道父类是否有该方法,对于g()方法来说,它只是生成了一个新的方法,
* 并没有覆盖掉父类中的g()方法。
*/
//@Override
public final void f(){
System.out.println("OverridingPrivate2.f()");
}
public void g(){
System.out.println("OverridingPrivate2.g()");
}
} public class FinalOverridingIllusion{
public static void main(String[] args) {
OverridingPrivate2 op2 = new OverridingPrivate2();
op2.f();
op2.g(); // 可以向上转型
OverridingPrivate op = op2;
//! op.f(); // 父类中final方法对子类来说是不可见的
//! op.g();
WithFinals wf = op2;
// wf.f();
// wf.g();
}
}
/*output:
OverridingPrivate2.f()
OverridingPrivate2.g()
*/

分析:

  覆盖何时发生:

    1,子类中出现与父类完全一致的方法

    2. 子类可以通过向上转型为父类,并调用父类中的那个方法

  若父类中某个方法被声明为final或者private,那么这个方法对子类来说是不可见的,就算在子类中创建了与父类一模一样的方法,这也是一个新的方法,而不是从父类中覆盖的方法。

final类:

  即该类不能被继承,不管是你还是别人,也就是这个类不需要做任何变动,也不需要任何子类,例如String类。

例子:

class SmallBrain{}

final class Dinosaur{
int i = 7;
int j = 1;
SmallBrain x = new SmallBrain();
void f(){}
}
// error: The type Further cannot subclass the final class Dinosaur
// Dinosaur类不能有子类
// class Further extends Dinosaur{} public class Jurassic {
public static void main(String[] args) {
Dinosaur n = new Dinosaur();
n.f();
n.i = 40;
n.j++;
}
}

当final作用于变量、参数、方法和类时该如何处理的更多相关文章

  1. Java中final关键字修饰变量、方法、类的含义是什么

    Java中的关键字final修饰变量.方法.类分别表示什么含义? 先看一个简单的介绍 修饰对象 解释说明 备注 类 无子类,不可以被继承,更不可能被重写. final类中的方法默认是final的 方法 ...

  2. static、final修饰的变量和方法能否被继承的问题

    首先定义父类和子类 public class Parent { protected static String a = "static"; final String b = &qu ...

  3. Java final 关键词修饰类、方法、变量

    1. final修饰类  被修饰的类不能被继承,也没有子类.假如随意创建这些类的子类,子类可能会错误的修改父类的实现细节.出于安全原因,类的实现细节不允许有任何改动.在创建对象模型的时候,确信这个类不 ...

  4. 继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类。 (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法。 (3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承。 (4)子类中定义的成员方法,并且这个方法的名字返回类型,以及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。 分析以上程

    继承的基本概念: (1)Java不支持多继承,也就是说子类至多只能有一个父类. (2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法.(3)子类中定义的成员变量和父类中定义的 ...

  5. 【问题】Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数

    [问题]Asp.net MVC 的cshtml页面中调用JS方法传递字符串变量参数. [解决]直接对变量加引号,如: <button onclick="deleteProduct('@ ...

  6. final变量、方法与类

    学习内容: 一.final变量 1.设定为final的变量,其值不可被改变. 2.final定义的变量必须在声明时对其进行赋值操作. 3.final可以修饰对象.被修饰为final的对象,只能恒定指向 ...

  7. 测试 Java 类的非公有成员变量和方法

    引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...

  8. Action接收页面传来的参数方法

    接收页面传来的参数方法 1.第一种:在action中设置相应的变量 在相应的action中设置与将要传进来的参数名相同的变量 eg: 页面传给后台两个参数 name=chance & age ...

  9. java中的反射机制,以及如何通过反射获取一个类的构造方法 ,成员变量,方法,详细。。

    首先先说一下类的加载,流程.只有明确了类这个对象的存在才可以更好的理解反射的原因,以及反射的机制. 一.  类的加载 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三 ...

随机推荐

  1. Jenkins项目部署使用教程-----02视图及项目添加

    注意:此以我公司为例,以svn上传代码 一.添加视图 1.点击右上角”+”号,新建新视图 勾选在该视图下显示的项目或者在该视图新建项目,点保存即可. 二.新建项目 1.点击左上角的新建,创建新项目. ...

  2. Java web学习 Cookie&&Session

    cookie&&session 会话技术 从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话.会 话技术就是记录这次会话中客户端的状态与数据的. 会话技术分为Coo ...

  3. JS实现移动端购物车左滑删除功能

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name ...

  4. 在浏览器里点击input输入框输入,会展示默认的历史下拉菜单

    给input设置autocomplete="off"属性可解决此问题

  5. progress 相关事件 异步 ajax

    loadstart — Fires when the fi rst byte of the response has been received.progress — Fires repeatedly ...

  6. 线上Mysql数据库崩溃事故的原因和处理

    前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...

  7. NFS服务器的安装与配置

    由于实验室的项目需要实现在CephFS之上建立NFS之上,所以记录一下NFS服务器的安装与配置流程. 1.NFS服务的简介: NFS 是 Network File System 的缩写,是Sun公司于 ...

  8. 基于HTML5的WebGL经典3D虚拟机房漫游动画

    第一人称在 3D 中的用法要参考第一人称在射击游戏中的使用,第一人称射击游戏(FPS)是以第一人称视角为中心围绕枪和其他武器为基础的视频游戏类型 ; 也就是说,玩家通过主角的眼睛来体验动作.自从流派开 ...

  9. word中表格第一列序号的设置

    表格中序号问题 1.新建一个表格.第一列选择编号后,编号后有tab,如下图 2.选中表格的编号,点击新建列表样式, 3.将编号后的字符改成nothing,在将单元格改成居中即可 4.在将单元格改成居中 ...

  10. CMSIS_RTOS_Tutorial自译中文版

    一.序言 本资料是Trevor Martin编写的<The Designers Guide to the Cortex-M Processor Family>的摘要,并得到Elsevier ...