标签:
关于于Java关键字主要要用到有三种情况:数据,方法,类。
final数据:
当我们需要一个永远不改变的编译时常量和运行时被初始化的不希望被改变的值的时候,我们需要将数据恒定。
对于在编译期常量这件事情,编译器可以将该常量值带入到任何可能用到它的计算式中,也就是说在编译时执行计算式,这样就减轻了一些运行时的负担。在java中这样的数字必须时基本类型,并且以关键字final表示,在对这个常量进行定义的时候,必须对其进行赋值。
一个既是static又是final的域只占据一段不能改变的存储空间。
public class Main{ static final int number1 = 5; static final int number2 = 6; private final int j; static int number3 = 5; static int number4= 6; public Main(){ j=10; } public static void main(String[ ] args) { int product1 = number1 * number2; //line A int product2 = number3 * number4; //line B } }
对这段代码进行反编译可以得到:
public class Main { static final int number1 = 5; static final int number2 = 6; private final int j; static int number3 = 5; static int number4 = 6; public Main() { this.j = 10; } public static void main(String[] args) { int product1 = 30; int product2 = number3 * number4; } }
同过这个我们可以知道当number1和number2在编译的时候已经计算了。
当对对像引用而不是基本类型运行final的时候,其含义会有一点令人迷茫,对于基本类型final使得数值恒定不变,而用于对象引用的时候,final使得引用恒定不变,一旦引用被初始化指向一个对象,就无法在把其改为指向另一个对象了,然后对象自身却是可以被修改的(这一限制也包含数组,因为数组也是对象),我们需要关注的是定义static强调于只有一份,而定义final强调不变,我们不能因为某数据是final修饰就认为在编译程序的时候知道它的值,比如在运行时候才能生成的数。
java允许在参数列表中以声明的方式将参数声明为final,这就意味着无法在该方法中更改引用的对象。
class Gizmo{ public void spin(){} } public class Main{ void with(final Gizmo g){ g=new Gizmo();//error!!! } void without(Gizmo g){ g=new Gizmo(); g.spin(); } int g(final int i){ return i+1; } public static void main(String[ ] args) { Main main=new Main(); Gizmo gizmo=new Gizmo(); main.without(null); main.with(gizmo); } }
final方法:
使用final方法的原因有两个,一个是把方法锁定,以防止任何继承类修改它的含义,第二个是效率的问题。
final关键字和private关键字:类中所有的private关键字都隐式的指定为final的,由于无法取用private方法,所以就无法覆盖它,可以对private方法添加final修饰词,但这并不能给方法增加任何额外的意义。“覆盖只有在某方法是基类的接口”的一部分的时候才会出现,即必须能将一个对象向上转型为它的基本类型并调用相同的方法。
这里增添一点小提示:关于方法覆盖和方法重载。
方法重载:这个是发生在编译时的。方法重载也被称为编译时多态,因为编译器可以根据参数的类型来选择使用哪个方法。
public class { public static void evaluate(String param1); // method #1 public static void evaluate(int param1); // method #2 }如果要编译下面这段的话;
1 evaluate(“My Test Argument passed to param1”);它会根据传入的参数是字符串常量,生成调用#1方法的字节码。
方法覆盖:这个是在运行时发生的。方法重载被称为运行时多态,因为在编译期编译器不知道并且没法知道该去调用哪个方法。JVM会在代码运行的时候做出决定。
public class A { public int compute(int input) { //method #3 return 3 * input; } } public class B extends A { @Override public int compute(int input) { //method #4 return 4 * input; } }子类B中的compute(..)方法重写了父类的compute(..)方法。如果编译器遇到下面的代码:
public int evaluate(A reference, int arg2) { int result = reference.compute(arg2); }
编译器是没法知道传入的参数reference的类型是A还是B。因此,只能够在运行时,根据赋给输入变量“reference”的对象的类型(例如,A或者B的实例)来决定调用方法#3还是方法#4.
final类:
当将某个类定义为final的时候,就表明了这个类不能被继承,对这个类永远不需要做任何的变动。但是需要注意的是,在类中的域依旧可以按照个人的意愿来进行选择是不是要final而不是一定要用final.
标签:
原文地址:http://www.cnblogs.com/aizhiyuan/p/5366451.html