之前一直在查找方法对象之类的问题,今天正好有机会和大家讨论一下.

1.用final关键字设置常数

很多程序设计语言都有自己的方法告知编译器某个数据是“常数”。常数重要应用于下述两个方面:
(1) 编译期常数,它永久不会转变
(2) 在运行期初始化的一个值,我们不希望它发生变化
对于编译期的常数,编译器(程序)可将常数值“封装”到须要的计算过程里。也就是说,计算可在编译期间提早执行,从而节省运行时的一些开销。在Java中,这些形式的常数必须属于基本数据类型(Primitives),而且要用final关键字进行抒发。在对这样的一个常数进行定义的时候,必须给出一个值。
无论static还是final字段,都只能存储一个数据,而且不得转变。
若随同对象句柄应用final,而不是基本数据类型,它的含意就稍微让人有点儿含糊了。对于基本数据类型,final会将值变成一个常数;但对于对象句柄,final会将句柄变成一个常数。进行声明时,必须将句柄初始化到一个详细的对象。而且永久不能将句柄变成指向另一个对象。然而,对象本身是可以修改的。Java对此未提供任何手腕,可将一个对象直接变成一个常数(但是,我们可自己编写一个类,使其中的对象拥有“常数”效果)。这一限制也适用于数组,它也属于对象。
下面是演示final字段用法的一个例子:

//: FinalData.java
//The effect of final on fields

class Value {
 int i = 1;
}

public class FinalData {
 // Can be compile-time constants
 final int i1 = 9;
 
 static final int I2 = 99;
 // Typical public constant:
 public static final int I3 = 39;
 // Cannot be compile-time constants:
 final int i4 = (int) (Math.random() * 20);
 static final int i5 = (int) (Math.random() * 20);
 
 static int i6 = 8;

Value v1 = new Value();
 final Value v2 = new Value();
 static final Value v3 = new Value();
 // ! final Value v4; // Pre-Java 1.1 Error:
 // no initializer
 // Arrays:
 final int[] a = { 1, 2, 3, 4, 5, 6 };

public void print(String id) {
  System.out.println(id + ": " + "i4 = " + i4 + ", i5 = " + i5);
 }

public static void main(String[] args) {
  FinalData fd1 = new FinalData();
     //! fd1.i1++;// Error: can't change value
  fd1.v2.i++; // Object isn't constant!
  System.out.println(fd1.v2.i);
  fd1.v1 = new Value(); // OK -- not final
  for (int i = 0; i < fd1.a.length; i++)
   fd1.a[i]++; // Object isn't constant!
  //! fd1.v2 = new Value(); // Error: Can't
  //fd1.v3 = new Value(); // change handle
   //fd1.a = new int[3];

fd1.print("fd1");
  System.out.println("Creating new FinalData");
  FinalData fd2 = new FinalData();
//  fd1.print("fd1");
//  fd2.print("fd2");
  
  fd2.i6++;
  System.out.println(fd2.i6);
 }
} // /:~

由于i1和I2都是拥有final属性的基本数据类型,并含有编译期的值,所以它们除了能作为编译期的常数应用外,在任何导入方式中也不会涌现任何不同。I3是我们体验此类常数定义时更典型的一种方式:public表现它们可在包外应用;Static强调它们只有一个;而final标明它是一个常数。注意对于含有牢固初始化值(即编译期常数)的fianl static基本数据类型,它们的名字根据规则要全体采用大写。也要注意i5在编译期间是未知的,所以它没有大写。
不能由于某样东西的属性是final,就认定它的值能在编译时代知道。i4和i5向大家证明了这一点。它们在运行期间应用随机生成的数字。例子的这一部份也向大家揭露出将final值设为static和非static之间的差异。只有当值在运行期间初始化的前提下,这类差异才会揭露出来。因为编译期间的值被编译器认为是相同的。这类差异可从输出结果中看出:

fd1: i4 = 15, i5 = 9
Creating

new

FinalData fd1: i4 = 15, i5 = 9 fd2: i4 = 10, i5 = 9

注意对于fd1和fd2来讲,i4的值是独一的,但i5的值不会由于创立了另一个FinalData对象而发生转变。那是因为它的属性是static,而且在载入时初始化,而非每创立一个对象时初始化。
从v1到v4的变量向我们揭露出final句柄的含意。正如大家在main()中看到的那样,并不能认为由于v2属于final,所以就不能再转变它的值。然而,我们确切不能再将v2绑定到一个新对象,因为它的属性是final。这便是final对于一个句柄的确切含意。我们会发现一样的含意亦适用于数组,后者只不过是另一种类型的句柄而已。将句柄变成final看起来仿佛不如将基本数据类型变成final那么有效。

每日一道理
信念是巍巍大厦的栋梁,没有它,就只是一堆散乱的砖瓦;信念是滔滔大江的河床,没有它,就只有一片泛滥的波浪;信念是熊熊烈火的引星,没有它,就只有一把冰冷的柴把;信念是远洋巨轮的主机,没有它,就只剩下瘫痪的巨架。

2.空白final
Java 1.1答应我们创立“空白final”,它们属于一些特殊的字段。尽管被声明成final,但却未失掉一个初始值。无论在哪种情况下,空白final都必须在现实应用前失掉正确的初始化。而且编译器会自动保障这一划定得以贯彻。然而,对于final关键字的各种应用,空白final拥有最大的灵活性。举个例子来讲,位于类外部的一个final字段现在对每一个对象都可以有所不同,同时仍然坚持其“不变”的本质。下面列出一个例子:

package com.finaltest;

class Poppet{
 
}

public class BlankFinal {
   
 final int i = 0;
 final int j;
 final Poppet p;
 
 public BlankFinal() {
       j=1;
       p = new Poppet();
 }
 
 public BlankFinal(int x){
  j = x;
  p = new Poppet();
 }
 
 public static void main(String[] args) {

BlankFinal bf = new BlankFinal();
 }

}

现在强行要求我们对final进行赋值处理——要么在定义字段时应用一个抒发 式,要么在每一个构建器中。这样就可以确保final字段在应用前取得正确的初始化。

3. final自变量
Java 1.1答应我们将自变量设成final属性,方法是在自变量列表中对它们进行恰当的声明。这意味着在一个方法的外部,我们不能转变自变量句柄指向的东西。如下所示:

//Using "final" with method arguments

class Gizmo{
 public void spin(){}
}

public class FinalArguments {

void with(final Gizmo g){
  //! g = new Gizmo();//Illdgal -- g is final
  g.spin();
 }
 
 void without(Gizmo g){
  g = new Gizmo();
  g.spin();
 }
 
 void f(final int i){
  //i++;//i can't change
 }
 
 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自变量分配一个null(空)句柄,同时编译器不会捕获它。这与我们对非final自变量采取的操纵是一样的。
方法f()和g()向我们展示出基本类型的自变量为final时会发生什么情况:我们只能读取自变量,不可转变它。

4.final方法
之所以要应用final方法,可能是出于对两方面来由的考虑。第一个是为方法“上锁”,防止任何继承类转变它的原来含意。设计程序时,若希望一个方法的行为在继承期间坚持不变,而且不可被覆盖或改写,就可以采取这类做法。
采用final方法的第二个来由是程序执行的效率。将一个方法设成final后,编译器就可以把对那个方法的所有调用都置入“嵌入”调用里。只要编译器发现一个final方法调用,就会(根据它自己的判断)忽略为执行方法调用机制而采取的常规代码插入方法(将自变量压入堆栈;跳至方法代码并执行它;跳回来;清除堆栈自变量;最后对返回值进行处理)。相反,它会用方法主体内现实代码的一个副原来替换方法调用。这样做可防止方法调用时的系统开销。当然,若方法体积太大,那么程序也会变得雍肿,可能受到到不到嵌入代码所带来的任何性能晋升。因为任何晋升都被花在方法外部的时间抵消了。Java编译器能自动侦测这些情况,并很是“理智”地决定是不是嵌入一个final方法。然而,最好还是不要完全相信编译器能正确地作出所有判断。通常,只有在方法的代码量非常少,或者想明白禁止方法被覆盖的时候,才应考虑将一个方法设为final。
类内所有private方法都自动成为final。由于我们不能访问一个private方法,所以它绝对不会被其他方法覆盖(若强行这样做,编译器会给出错误提示)。可为一个private方法添加final指示符,但却不能为那个方法提供任何额外的含意。

5.final类
如果说整个类都是final(在它的定义前冠以final关键字),就标明自己不希望从这个类继承,或者不答应其他任何人采取这类操纵。换言之,出于这样或那样的原因,我们的类肯定不须要进行任何转变;或者出于安全方面的来由,我们不希望进行子类化(子类处理)。
除此以外,我们或许还考虑到执行效率的问题,并想确保涉及这个类各对象的所有行动都要尽可能地有效。如下所示:

//Making an entire class final

class SmallBrain{
 
}

final class Dinosaur{
 int i=7;
 int j=1;
 SmallBrain x = new SmallBrain();
 
 void f(){}
}

public class Jurassic {
 
 public static void main(String[] args) {

Dinosaur n = new Dinosaur();
  n.f();
  n.i=40;
  n.j++;
 }

}

注意数据成员既可以是final,也可以不是,取决于我们详细选择。应用于final的规则一样适用于数据成员,无论类是不是被定义成final。将类定义成final后,结果只是禁止进行继承——没有更多的限制。然而,由于它禁止了继承,所以一个final类中的所有方法都默认为final。因为此时再也无法覆盖它们。所以与我们将一个方法明白声明为final一样,编译器此时有相同的效率选择。
可为final类内的一个方法添加final指示符,但这样做没有任何意义。

 

文章结束给大家分享下程序员的一些笑话语录: 大家喝的是啤酒,这时你入座了。
你给自己倒了杯可乐,这叫低配置。
你给自已倒了杯啤酒,这叫标准配置。
你给自己倒了杯茶水,这茶的颜色还跟啤酒一样,这叫木马。
你给自己倒了杯可乐,还滴了几滴醋,不仅颜色跟啤酒一样,而且不冒热气还有泡泡,这叫超级木马。
你的同事给你倒了杯白酒,这叫推荐配置。
菜过三巡,你就不跟他们客气了。
你向对面的人敬酒,这叫p2p。
你向对面的人敬酒,他回敬你,你又再敬他……,这叫tcp。
你向一桌人挨个敬酒,这叫令牌环。
你说只要是兄弟就干了这杯,这叫广播。
有一个人过来向这桌敬酒,你说不行你先过了我这关,这叫防火墙。
你的小弟们过来敬你酒,这叫一对多。
你是boss,所有人过来敬你酒,这叫服务器。
酒是一样的,可是喝酒的人是不同的。
你越喝脸越红,这叫频繁分配释放资源。
你越喝脸越白,这叫资源不释放。
你已经醉了,却说我还能喝,叫做资源额度不足。
你明明能喝,却说我已经醉了,叫做资源保留。
喝酒喝到最后的结果都一样
你突然跑向厕所,这叫捕获异常。
你在厕所吐了,反而觉得状态不错,这叫清空内存。
你在台面上吐了,觉得很惭愧,这叫程序异常。
你在boss面前吐了,觉得很害怕,这叫系统崩溃。
你吐到了boss身上,只能索性晕倒了,这叫硬件休克。

方法对象java final关键字的用法相关推荐

  1. java final char_java基本数据类型总结 类型转换 final关键字的用法

    java基本数据类型总结 Java数据类型总结 数据类型在计算机语言里面,是对内存位置的一个抽象表达方式,可以理解为针对内存的一种抽象的表达方式.接触每种语言的时候,都会存在数据类型的认识,有复杂的. ...

  2. 【Java基本功】一文读懂final关键字的用法

    本文主要介绍了final关键字的基本使用方法及原理 final关键字可以修饰类.方法和引用. 修饰类,该类不能被继承.并且这个类的对象在堆中分配内存后地址不可变. 修饰方法,方法不能被子类重写. 修饰 ...

  3. 【Java基本功】一文读懂final关键字的用法 1

    本文主要介绍了final关键字的基本使用方法及原理 final关键字可以修饰类.方法和引用. 修饰类,该类不能被继承.并且这个类的对象在堆中分配内存后地址不可变. 修饰方法,方法不能被子类重写. 修饰 ...

  4. java final定义_Java中final关键字的用法

    final在Java中并不常用,然而它却为我们提供了诸如在C语言中定义常量的功能,不仅如此,final还可以让你控制你的成员.方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中 ...

  5. java中final关键字的用法

    final:adj. 最终的,不可改变的 我们就取其字面意思"不可改变的". final可以修饰类.方法.变量.那么分别是什么作用呢? (1)修饰类:表示类不可被继承 (2)修饰方 ...

  6. java抽象类与final关键字的用法

    抽象类:使用abstract关键字定义的类就是抽象类  很多具有相同特征和行为的  对象  可以抽象成一个     类  很多具有相同 特征和行为的  类    可以抽象成一个      抽象类 抽象 ...

  7. java——final关键字、权限、内部类、引用类型

    final关键字代表最终.不可改变的.常见四种用法: 1. 可以用来修饰一个类 2. 可以用来修饰一个方法 3. 还可以用来修饰一个局部变量 4. 还可以用来修饰一个成员变量 当final关键字用来修 ...

  8. java final 关键字

    java的final关键字 前言 final是 最终 的意思. 在java这门编程语言中,final是一个关键字,它可以被用来修饰类,变量以及成员方法. 被final修饰的变量,又叫被称为 自定义常量 ...

  9. Java——final关键字,String为什么不可变

    目录 final是什么? 一.修饰类 二.修饰变量 三.修饰方法 String为什么不可变? 不知道大家有没有这样的疑问:我们在使用某些Java的类或者方法.属性(比如:String类)时,总是会发现 ...

最新文章

  1. 谈谈Tomcat连接器
  2. VMWare虚拟机连接方式
  3. struts实战--添加功能(重点文件上传)
  4. 栅格矢量化_学会用栅格系统,普通LOGO秒变高大上
  5. MVC+LINQToSQL的Repository模式之(二)数据基类
  6. Concurrent and Parallel
  7. c# json 汉字乱码_json.net中文乱码问题
  8. sap 打印预览界面点击打印时记录打印次数_9个Excel打印神技巧!从此打印不求人!...
  9. MacDev.GarbageCollectionIsDeprecated-WhenXcodeCompileMacAppProject
  10. 毕业设计 - 基于JAVA人脸识别管理系统(人脸搜索与人脸库管理)
  11. 爆火的羊了个羊背后暗含的广告变现逻辑是什么?
  12. android电量优化方法,Android性能优化——电池使用优化
  13. selectpicker 清空选项_boostrap selectpicker 用法
  14. UEFI Application
  15. 腾讯企业邮箱满了,如何清空邮箱?
  16. Tiger DAO VC:DAO组织风险投资时代来临
  17. yield 和 yield*
  18. 中国蚁剑下载时,出现“无法成功完成操作,文件包含病毒或潜在的垃圾软件”报错的解决方案
  19. 解读正则化 LASSO回归 岭回归
  20. mantis问题状态

热门文章

  1. ORACLE关闭启动的诡异错误
  2. JAVA修饰符类型(public,protected,private,friendly)
  3. 构建多域名Exchange 2010邮件系统
  4. 使用Kickstart+Apache+Dhcp+Pxe无人值守安装操作系统
  5. 搜索引擎优化(独立阐述)
  6. .NET新手系列(八)
  7. Kubernetes — 安装 Metrics Server
  8. Ceph 的用户管理与认证
  9. python之socketserver实现并发
  10. 配置nginx下别名alias支持PHP fastcgi解析