Java 开发中static 和 final 关键字
2016-06-04 08:40
561 查看
我们在Java 开发中大量使用static 和 final关键字,面试中也经常被提到.下面就这两个关键字的用法进行讲解.
1.只想为特定域分配单一存储空间,而不考虑究竟要创建多少对象,甚至不创建任何对象.
2.希望某个方法不与包含他的类的对象关联在一起.即使没有创建对象也能够调用这个方法.
那么这两句话的含义是啥呢,我们还是来看一个示例.
上面这个结果是大家都可以猜到的,接着我们让st1.i 或st2.i 自增,看一下输出结果.
大家看出区别了吧,static 字段对每个类来说都只有一份存储空间 StaticTest 中的i 变量占据了单一的存储空间,保证了创建多个StaticTest 对象时, 变量i 也只有一份. st1.i和st2.i指向了同一个存储空间.
static 是不是很简单,下面我们看final 关键字,讲解的过程中会穿插着用一下static 关键字
1.一个永不改变的编译时常量.
2.一个在运行时被初始化的值,而你不希望它被改变.
当对基本类型时,final 使数值恒定不变,而应用于对象引用,final 使引用恒定不变,但是对象自身确实可以被修改的.
下面的示例示范了final 修饰数据的情况.
代码中无法通过编译器检测的我已经在注释中标上了大大的error.原因就是上面提到的被fianl 修饰过的引用,一旦被初始化指向一个对象,就没有办法把它改为指向另一个对象了, 好专一啊………..
专一的人是不是都被final 修饰过~~~ 有点扯远了
我们还需要注意一个细节,当我输出i4 和 INT_5 ,一个没有被static 修饰过一个被修饰过,没有被修饰的,两个对象,两个不同的值.被static修饰过 在类中只有一份,同时又是不可以修改的,因此一但被赋值,也就不会改变了.
空白final:
允许刚开始时,被final 修饰的变量不用初始化,但后面使用的时候一定要初始化.
final修饰参数
fianl 修饰的参数,无法在方法中更改参数引用所指向的对象.
方法貌似被”覆写”了,其实不然,覆写的概念: “只有非private 方法才能被覆写”,对于private 修饰的方法是没有覆写这个概念的.可以把它看做是隐藏在类中的程序代码,只不过具有相同的名字而已! 好坑啊~~
ok 这两个关键字就介绍到这里,相信你再次使用它们的时候,会有更加清晰的认识.
参考文章:
thinking in java
static关键字
通常我们在下述两种情况下用static :1.只想为特定域分配单一存储空间,而不考虑究竟要创建多少对象,甚至不创建任何对象.
2.希望某个方法不与包含他的类的对象关联在一起.即使没有创建对象也能够调用这个方法.
那么这两句话的含义是啥呢,我们还是来看一个示例.
static 修饰字段:
public class StaticTest { static int i =26; public static void main(String[] args){ StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest(); System.out.println(st1.i); System.out.println(st2.i); } } 输出结果: 26 26
上面这个结果是大家都可以猜到的,接着我们让st1.i 或st2.i 自增,看一下输出结果.
public class StaticTest { static int i =26; public static void main(String[] args){ StaticTest st1 = new StaticTest(); StaticTest st2 = new StaticTest(); st1.i++; System.out.println(st1.i); System.out.println(st2.i); } } 输出结果: 27 27
大家看出区别了吧,static 字段对每个类来说都只有一份存储空间 StaticTest 中的i 变量占据了单一的存储空间,保证了创建多个StaticTest 对象时, 变量i 也只有一份. st1.i和st2.i指向了同一个存储空间.
static 修饰方法:
一句话,没有创建对象,也能使用该类中的方法.这里就不贴代码了.static 是不是很简单,下面我们看final 关键字,讲解的过程中会穿插着用一下static 关键字
final 关键字
final 关键字的意思是 “这里是无法改变的”,下面我们会讨论被final 修饰的三种情况.1.fianl 修饰”数据”
我们开发的时候可能希望数据是恒定不变的,比如:1.一个永不改变的编译时常量.
2.一个在运行时被初始化的值,而你不希望它被改变.
当对基本类型时,final 使数值恒定不变,而应用于对象引用,final 使引用恒定不变,但是对象自身确实可以被修改的.
下面的示例示范了final 修饰数据的情况.
package com.example; import java.util.Random; public class FinalData { private static Random rand = 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 = rand.nextInt(20); static final int INT_5 =rand.nextInt(20); private Value v1 = new Value(11); private final Value v2 = new Value(11); private static final Value VAL_3 = new Value(33); private final int[] a = {6,5,4,3,2,1}; public String toString(){ return id+": "+i4+", INT_5=" + INT_5; } public static void main(String[] args){ FinalData fd1 = new FinalData("fd1"); fd1.v2.i++; fd1.v1 = new Value(9); for(int i=0;i<fd1.a.length;i++){ fd1.a [i]++; //fd1.v2 = new Value(0);// error //fd1.VAL_3 = new Value(1);// error //fd1.a = new int[3]; //error } FinalData fd2 = new FinalData("fd2"); System.out.println(fd1); System.out.print(fd2); } } class Value{ int i; public Value(int i){ this.i =i; } } 输出结果: fd1: 15, INT_5=18 fd2: 13, INT_5=18
代码中无法通过编译器检测的我已经在注释中标上了大大的error.原因就是上面提到的被fianl 修饰过的引用,一旦被初始化指向一个对象,就没有办法把它改为指向另一个对象了, 好专一啊………..
专一的人是不是都被final 修饰过~~~ 有点扯远了
我们还需要注意一个细节,当我输出i4 和 INT_5 ,一个没有被static 修饰过一个被修饰过,没有被修饰的,两个对象,两个不同的值.被static修饰过 在类中只有一份,同时又是不可以修改的,因此一但被赋值,也就不会改变了.
空白final:
允许刚开始时,被final 修饰的变量不用初始化,但后面使用的时候一定要初始化.
package com.example; /** * blank final */ public class BlankFinal { private final int i= 0; private final int j; private final Poppet p; public BlankFinal(){ j=1; p =new Poppet(1); } public BlankFinal(int x){ j=x; p=new Poppet(x); } public static void main(String[] args ){ new BlankFinal(); new BlankFinal(26); } } class Poppet{ private int i; Poppet(int ii){ i = ii; } }
final修饰参数
fianl 修饰的参数,无法在方法中更改参数引用所指向的对象.
public final class People { public void swim(){} } class Animail{ void with(final People people){ // people = new People();//error } }
final 修饰方法
被final 修饰过的方法,子类是无法覆盖的,需要注意的一点private 修饰方法都隐式的指定为方法 添加了final .下面的代码有点迷惑性.public class withFinals { private final void f(){ System.out.println("withFinals.f()"); } // automatically add fianl private void g(){ System.out.println("widthFinals.g()"); } } class OverringPrivate extends withFinals{ private final void f(){ System.out.println("OverringPrivate.f()"); } private final void g(){ System.out.println("OverringPrivate.g()"); } } class OverringPrivate2 extends OverringPrivate{ public final void f(){ System.out.println("OverringPrivate2.f()"); } public final void g(){ System.out.println("OverringPrivate2.g()"); } } class FinalOverridingIllusion{ public static void main(String[] args){ OverringPrivate2 op2 = new OverringPrivate2(); op2.f(); op2.g(); OverringPrivate op = op2; // op.f(); error // op.g(); error withFinals wf = op2; // wf.f(); error // wf.g(); error } }
方法貌似被”覆写”了,其实不然,覆写的概念: “只有非private 方法才能被覆写”,对于private 修饰的方法是没有覆写这个概念的.可以把它看做是隐藏在类中的程序代码,只不过具有相同的名字而已! 好坑啊~~
final 修饰类
也是一句话,被final 修饰过得类,就表明该类是无法继承的,子类是无法继承和覆写.这里我们就不贴代码了,大家可以写个代码测一下.ok 这两个关键字就介绍到这里,相信你再次使用它们的时候,会有更加清晰的认识.
参考文章:
thinking in java
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法