Java中staticthis、super、final的用法_第1页
Java中staticthis、super、final的用法_第2页
Java中staticthis、super、final的用法_第3页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、?J a v a 中 st a t i c、 t h i s、 su p er 、 f i n a l 的 用 法 ?一、 static请先看下面这段程序:public class Hellopublic static void main(String args)/(1)看过这段程序,对于大多数学过 Java的从来说,都不陌生。即使没有学过Java,而学过其它的高级语言,例如 C ,那您也应该能看懂这段代码的意思。它只是简单的输出“Hello,world ,一点别的用处都没有,然而,它却展示了 static 关键字的主要用法。在1处,我们定义了一个静态的方法名为mai n,这就意味着告诉 Ja

2、va编译器,我这个方法不需要创立一个此类的对象即可使用。您还得您是怎么运行这个程序吗?一般,我们都是在命令行 下,打入如下的命令 (加下划线为手动输入 ):javac Hello.javajava HelloHello,world!这就是您运行的过程,第一行用来编译Hello.java 这个文件,执行完后,如果您查看当前,会发现多了一个Hello.class文件,那就是第一行产生的Java二进制字节码。第二行就是执行一个Java程序的最普遍做法。执行结果如您所料。在2中,您可能会想,为什么要这样才能输出。好,我们来分解一下这条语句。(如果没有安装Java文档,请到Sun的官方网站浏览J2SE

3、API)首先,System 是位于 java.lang 包中的一个核心类,如果您查看它的定义,您会发现有这样一行:public static finalPrintStream out;接着在进一步,点击PrintStream这个超链接,在 METHOD页面,您会看到大量定义的方法,查找 println ,会有这样一行:public void println(String x) 。好了,现在您应该明白为什么我们要那样调用了, out 是 System 的一个静态变量,所以可以直 接使用,而 out 所属的类有一个 println 方法。静态方法通常,在一个类中定义一个方法为static,那就是说

4、,无需本类的对象即可调用此方法。如下所示:class Simplestatic void go()public class Calpublic static void main(String args)Simple.go();调用一个静态方法就是 “类名.方法名 静,态方法的使用很简单如上所示。一般来说,静态方法 常常为应用程序中的其它类提供一些实用工具所用,在Java 的类库中大量的静态方法正是出于此目的而定义的。静态变量 静态变量与静态方法类似。所有此类实例共享此静态变量,也就是说在类装载时,只分配一 块存储空间,所有此类的对象都可以操控此块存储空间,当然对于final 那么另当别论了。看

5、下面这段代码:static int c=0;static void inc()c+;class Countpublic static void prt(String s)public static void main(String args)Value v1,v2;v1=new Value();v2=new Value();prt(v1.c=+v1.c+ v2.c=+v2.c);v1.inc();prt(v1.c=+v1.c+ v2.c=+v2.c);结果如下:v1.c=0 v2.c=0v1.c=1 v2.c=1由此可以证明它们共享一块存储区。 static 变量有点类似于 C 中的全局变量的

6、概念。值得探讨 的是静态变量的初始化问题。我们修改上面的程序:运行结果如下:v1.c=0 v2.c=0v1.c=27 v2.c=27v1.c=15 v2.c=15ct.c=10v1.c=10 v2.c=10v1.c=11 v2.c=11ct.c=11这个程序展示了静态初始化的各种特性。如果您初次接触Java,结果可能令您吃惊。可能会对static后加大括号感到困惑。首先要告诉您的是,static定义的变量会优先于任何其它非static变量,不管其出现的顺序如何。正如在程序中所表现的,虽然v出现在v1和v2的前面,但是结果却是v1和v2的初始化在v的前面。在static后面跟着一段代码,这是用来

7、进行显式的静态变量初始化,这 段代码只会初始化一次,且在类被第一次装载时。如果您能读懂并理解这段代码,会帮助您对 static 关键字的认识。在涉及到继承的时候,会先初始化父类的static 变量,然后是子类的,依次类推。非静态变量不是本文的主题,在此不做详细讨论,请参考Think in Java 中的讲解。静态类通常一个普通类不允许声明为静态的,只有一个内部类才可以。这时这个声明为静态的内部 类可以直接作为一个普通类来使用,而不需实例一个外部类。如下代码所示:public class StaticClspublic static void main(String args)OuterCls.

8、InnerCls oi=new OuterCls.InnerCls();InnerCls()输出结果会如您所料:InnerCls和普通类一样。内部类的其它用法请参阅 Think in Java 中的相关章节,此处不作详解。二、 this & super在上一篇拙作中,我们讨论了static的种种用法,通过用 static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量。但是,并不是说有了这种便利,您便可以随处使用,如果那样的话,您便需要认真考虑一下自己是否在用面向对 象的思想编程,自己的程序是否是面向对象的。好了,现在开始讨论this&supe

9、r 这两个关键字的意义和用法。在Java中,this通常指当前对象,super那么指父类的。当您想要引用当前对象的某种东西,比方 当前对象的某个方法,或当前对象的某个成员,您便可以利用this 来实现这个目的,当然, this 的另一个用途是调用当前对象的另一个构造函数,这些马上就要讨论。如果您想引用父类的某种东 西,那么非super莫属。由于this与super有如此相似的一些特性和与生俱来的某种关系,所以我们在 这一块儿来讨论,希望能帮助您区分和掌握它们两个。在一般方法中:最普遍的情况就是,在您的方法中的某个形参名与当前对象的某个成员有相同的名字,这时为了不至于混淆,您便需要明确使用thi

10、s关键字来指明您要使用某个成员,使用方法是“this成员名而不带this的那个便是形参。另外,还可以用“this方法名来引用当前对象的某个方法,但这时 this 就不是必须的了,您可以直接用方法名来访问那个方法,编译器会知道您要调用的是那一 个。下面的代码演示了上面的用法:private String name;private int age;DemoThis(String name,int age)setName(name); 您可以加上this来调用方法,像这样:this.setName(name);但这并不是必须的setAge(age);this.print();public void

11、setName(String name)this. name=n ame;此处必须指明您要引用成员变量public void setAge(int age)this.age=age;public void print()public static void main(String args)DemoThis dt=new DemoThis(Kevin,22);这段代码很简单,不用解释您也应该能看明白。在构造函数中您看到用this.print(), 您完全可以用 print() 来代替它,两者效果一样。下面我们修改这个程序,来演示super 的用法。public int c;private St

12、ring name;private int age;protected void setName(String name)=name;protected void setAge(int age)this.age=age;protected void print()public class DemoSuper extends Personpublic void print()super.print();public static void main(String args)DemoSuper ds=new DemoSuper();ds.setName(kevin);ds.set

13、Age(22);ds.print();在 DemoSuper 中,重新定义的 print 方法覆写了父类的 print 方法,它首先做一些自己的事情, 然后调用父类的那个被覆写了的方法。输出结果说明了这一点:DemoSuper:Name=kevin Age=22这样的使用方法是比拟常用的。另外如果父类的成员可以被子类访问,那您可以像使用 this 一 样使用它,用“supe父类中的成员名的方式,但常常您并不是这样来访问父类中的成员名的。在构造函数中:构造函数是一种特殊的方法,在对象初始化的时候自动调用。在构造函数中,this 和 super 也有上面说的种种使用方式,并且它还有特殊的地方,请看

14、下面的例子:class Personpublic static void prt(String s)Person()prt(A Person.);Person(String name)prt(A person name is:+name);public class Chinese extends PersonChinese()super(); /调用父类构造函数( 1)prt(A chinese.);/(4)Chinese(String name)super( name);/调用父类具有相同形参的构造函数(2)prt(his name is:+name);Chinese(String name

15、,int age)this( name);/调用当前具有相同形参的构造函数(3)prt(his age is:+age);public static void main(String args)Chinese cn=new Chinese();cn=new Chinese(kevin);cn=new Chinese(kevin,22);在这段程序中, this 和 super 不再是像以前那样用 “.连接一个方法或成员,而是直接在其后跟 上适当的参数,因此它的意义也就有了变化。 super 后加参数的是用来调用父类中具有相同形式的 构造函数,如1和2处。this后加参数那么调用的是当前具有相同

16、参数的构造函数,如3处。当然,在Chinese的各个重载构造函数中,this和super在一般方法中的各种用法也仍可使用,比方4处,您可以将它替换为“this.prt因为它继承了父类中的那个方法)或者是“super.prt (因为它是父类中的方法且可被子类访问),它照样可以正确运行。但这样似乎就有点画蛇添足的味道了。最后,写了这么多,如果您能对“this通常指代当前对象,super通常指代父类这句话牢记在 心,那么本篇便到达了目的,其它的您自会在以后的编程实践当中慢慢体会、掌握。另外关于本 篇中提到的继承,请参阅相关 Java 教程。三、 finalfinal在Java中并不常用,然而它却为我

17、们提供了诸如在C语言中定义常量的功能,不仅如此,final 还可以让您控制您的成员、方法或者是一个类是否可被覆写或继承等功能,这些特点使final在Java中拥有了一个不可或缺的地位,也是学习Java时必须要知道和掌握的关键字之一。final 成员当您在类中定义变量时,在其前面加上 final 关键字,那便是说,这个变量一旦被初始化便不可改变,这里不可改变的意思对根本类型来说是其值不可变,而对于对象变量来说其引用不可再 变。其初始化可以在两个地方,一是其定义处,也就是说在final 变量定义时直接给其赋值,二是在构造函数中。这两个地方只能选其一,要么在定义时给值,要么在构造函数中给值,不能同时

18、 既在定义时给了值,又在构造函数中给另外的值。下面这段代码演示了这一点:public class Batfinal PI=3.14; / 在定义时便给址值final int i; / 因为要在构造函数中进行初始化,所以此处便不可再给值final List list; / 此变量也与上面的一样Bat()i=100;list=new LinkedList();Bat(int ii,List l)i=ii;list=l;public static void main(String args)Bat b=new Bat();/b.i=25;/b.list=new ArrayList();b=new B

19、at(23,new ArrayList();此程序很简单的演示了 final 的常规用法。在这里使用在构造函数中进行初始化的方法,这使 您有了一点灵活性。如 Bat 的两个重载构造函数所示,第一个缺省构造函数会为您提供默认的值, 重载的那个构造函数会根据您所提供的值或类型为 final 变量初始化。然而有时您并不需要这种灵 活性,您只需要在定义时便给定其值并永不变化,这时就不要再用这种方法。在 main 方法中有两 行语句注释掉了,如果您去掉注释,程序便无法通过编译,这便是说,不管是 i 的值或是 list 的类 型,一旦初始化,确实无法再更改。然而 b 可以通过重新初始化来指定 i 的值或

20、list 的类型,输出 结果中显示了这一点:还有一种用法是定义方法中的参数为final ,对于根本类型的变量,这样做并没有什么实际意义,因为根本类型的变量在调用方法时是传值的,也就是说您可以在方法中更改这个参数变量而 不会影响到调用语句,然而对于对象变量,却显得很实用,因为对象变量在传递时是传递其引 用,这样您在方法中对对象变量的修改也会影响到调用语句中的对象变量,当您在方法中不需要 改变作为参数的对象变量时,明确使用 final 进行声明,会防止您无意的修改而影响到调用方法。另外方法中的内部类在用到方法中的参变量时,此参变也必须声明为 final 才可使用,如下代 码所示:public cl

21、ass INClassvoid innerClass(final String str)class IClassIClass()IClass ic=new IClass();public static void main(String args)INClass inc=new INClass();inc.innerClass(Hello);final 方法将方法声明为 final ,那就说明您已经知道这个方法提供的功能已经满足您要求,不需要进行 扩展,并且也不允许任何从此类继承的类来覆写这个方法,但是继承仍然可以继承这个方法,也 就是说可以直接使用。另外有一种被称为 inline 的机制,它会

22、使您在调用 final 方法时,直接将方法 主体插入到调用处,而不是进行例行的方法调用,例如保存断点,压栈等,这样可能会使您的程 序效率有所提高,然而当您的方法主体非常庞大时,或您在多处调用此方法,那么您的调用主体 代码便会迅速膨胀,可能反而会影响效率,所以您要慎用 final 进行方法定义。final 类当您将 final 用于类身上时,您就需要仔细考虑,因为一个 final 类是无法被任何人继承的,那 也就意味着此类在一个继承树中是一个叶子类,并且此类的设计已被认为很完美而不需要进行修 改或扩展。对于 final 类中的成员,您可以定义其为 final ,也可以不是 final 。而对于方法,由于所 属类为 final

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论