收藏 分享(赏)

Java开发技术大全.doc

上传人:hyngb9260 文档编号:4853038 上传时间:2019-01-16 格式:DOC 页数:32 大小:153.50KB
下载 相关 举报
Java开发技术大全.doc_第1页
第1页 / 共32页
Java开发技术大全.doc_第2页
第2页 / 共32页
Java开发技术大全.doc_第3页
第3页 / 共32页
Java开发技术大全.doc_第4页
第4页 / 共32页
Java开发技术大全.doc_第5页
第5页 / 共32页
点击查看更多>>
资源描述

1、3.5 方法的调用方法定义的目的,就是要给其他人使用。多数情况下,使用方法需要进行显示的方法调用。方法被调用之后,就会执行方法体内部的语句,完成预定义的功能。3.5.1 方法调用的形式根据方法的调用者与被调用的方法所处的位置,方法调用的形式可以分为两种: 调用者和被调用方法位于同一类中,形式如下:this.方法名(实际参数列表)在大多数情况下,关键字 this 可以省略。 调用者位于被调用方法所在类的外部,形式如下:对象名.方法名(实际参数列表) 或者 类名.方法名( 实际参数列表)实际参数列表是对应方法的形式参数列表,可以是 0 个或多个变量或表达式,如果超过一个,需用逗号分隔。下面是方法调

2、用的两个例子。【例 3.14】 同一类中调用方法示例。/-文件名 invokeMethod.java,程序编号 3.24-public class invokeMethodpublic void showMsg()System.out.println(“This is showMsg method“);public void callOther()showMsg(); /调用类中的另外一个方法,这里也可以写成 this.showMsg()public static void main(String args)/创建对象invokeMethod ob = new invokeMethod();o

3、b.callOther(); /调用 callOther()方法程序的输出如下:This is showMsg method在程序 3.24 中,方法 callOther()和方法 showMsg()处在同一个类中,所以调用后者时,直接使用方法名就可以。令人比较疑惑的地方是在 main()方法中,此处调用 callOther()方法使用了看似比较麻烦的办法:先创建一个对象 ob,在用“对象名.方法名()”的格式来调用该方法,这似乎是多此一举。实际上,在这里,这么做是必须的。main()方法是一个静态方法,它由系统来调用。系统在调用它的时候,并没有创建一个 invokeMethod 的对象,而

4、callOther()和 showMsg()方法都是实例方法,它们被调用时,都必须有对象的存在。所以必须在 main 中先创建一个对象 ob,才能调用这两个方法。从这一点来看,main 方法虽然处在 invokeMethod 类的内部,但它的表现却如同在类的“外部”一样。这么解释,读者可能还会有疑惑:为什么 callOther()又能够直接调用 showMsg(),难道它能保证在调用后者时,对象已经存在?答案确实如此,因为 callOther()本身是实例方法,它在被执行时,一定是有对象存在的。基于这个前提,它才能够直接调用 showMsg()方法。【例 3.15】 外部类调用方法示例。这里仍

5、然利用程序 3.24,另外再写一个类来使用 invokeMethod 类中的两个方法。/-文件名 invokeOther.java,程序编号 3.25-public class invokeOtherpublic static void main(String args)invokeMethod ob = new invokeMethod(); /创建对象ob.callOther(); /调用 callOther()方法%注意:需要将 invokeMethod.java 和 invokeOther.java 两个方法放在同一个目录下面,然后分别编译。后面如无特殊说明,需要用到两个或两个以上文件

6、的,都必须放在同一目录下编译。程序 3.25 和程序 3.24 的输出结果完全一样。细心的读者还会发现,在 invokeOther 类中的 main()方法和 invokeMethod 类中的 main()方法代码完全一样。在 3.7 和 3.8 节中,还将进一步解释这一现象。在 invokeOther 类中,还可以调用 showMsg()方法,形式还是 ob.showMsg()。读者可以自己改动程序 3.25 查看效果。3.5.2 方法调用的参数在定义一个方法时,程序员可能会根据需要列出一个参数表,这些参数被称为形式参数,简称为形参。在调用方法时,需要调用者提供与之相匹配的参数表,被称为实际

7、参数,简称为实参。这里的匹配有两个条件: 实参和形参的个数要相等。 实参和形参对应位置上的数据类型要相容。即数据类型相同,或者实参可以做自动类型转换转换成形参类型。图 3.5 方法调用的传值过程在方法调用发生时,系统会将实参的值按照位置关系一个一个传递给形参,即第一个实参传给第一个形参,第二个实参传给第二个形参,这个过程中,不会考虑形参和实参的名字。如图 3.5 所示。由于在 Java 中存在两种类型的数据:基本类型和复合类型。这两种类型的数据作为参数传递时,是有区别的。本节将分别介绍这两种情况。1基本类型作为参数当方法的参数是基本类型(包括整型、浮点和布尔型)时,它是通过传值方式进行调用的。

8、这种传递方式的特点是: 它所传递的实参的值是一个副本。 单值传递。实参本质上是一个可求值的表达式,它所求出来的值是一个基本类型。 单向传递。方法内部可以修改形参的值,但这种修改不会影响到对应的实参。直观来看,传值过程相当于一个赋值过程,实参是右值,形参是左值。它们发生联系只在调用的那一瞬间,以后二者之间再无关系。【例 3.16】 单向传值示例。/-文件名 invokeByValue.java,程序编号 3.26-public class invokeByValuepublic void tryChange(int ix)ix = ix * 2; /企图改变参数的值public void sho

9、wDiffer()int ix = 10;System.out.println(“调用 tryChange 方法之前,ix=“ + ix);/测试是否能改变实参的值tryChange(ix);System.out.println(“调用 tryChange 方法之后,ix=“ + ix);public static void main(String args)invokeByValue va = new invokeByValue();va.showDiffer();程序的输出如下:调用 tryChange 方法之前,ix=10调用 tryChange 方法之后,ix=10从本例中可以看出,尽

10、管在 tryChange()方法中,改变了形参 ix 的值,但对于实参 ix 并没有影响。从这个例子还可以看出,形参实际上是一个局部变量,它的作用域仅限于定义它的方法体内部。实参的名字是否和它相同都没有影响。单向传值可以防止程序员在无意的情况下改变实参的值,起到了降低程序间数据耦合度的作用。但在某些情况下,单向传值却会阻碍某些功能的实现。比如,要写一个方法实现两个参数交换值的功能。初学者可能会写成下面这个样子:public void swap(int a, int b)int t=a;a=b;b=t;然后这样来调用它:swap(a,b);很不幸,调用过后,会发现,a 和 b 的值没有任何改变。

11、因为在方法 swap中交换的只是形参 a 和 b 的值,这对于实参 a 和 b 来说,没有任何影响。实际上,在 Java 中,没有任何简单的方法能够实现上述交换两个基本变量的值,而只能把上面这段代码写在需要交换的地方。2复合类型作为参数如果形式参数不是基本类型,而是复合类型,比如类类型,那么实参和形参的表现行为和基本类型的参数会有一些区别。如果实参是一个类的对象,那么在调用相应的方法时,系统会将该对象的地址值传递给形参。例如,有一个类 onlyTest,actual 是它的一个对象作为实参,form 是它定义的形参对象,则调用时的传值情形如图 3.6 所示(假定类实例在内存中的存储地址为 0x

12、00ff)。在 Java 中虽然没有“指针”这一概念,程序员也不需要掌握它。但在系统内部,仍然是存在指针的。图 3.6 就是指针运用的示例。actual 和 form 指向了同一个对象实例,其中任何一个变量改变类实例中的值,都会对另外一个变量有所影响。对象的传值过程,其实是借用了 C/C+中指针传值的方法,造成的效果也完全相同。下面这个例子展示了对象传值的效果。【例 3.17】 对象传值示例。/-文件名 onlyTest.java,程序编号 3.27-public class onlyTestprivate int x = 0;/设置成员变量 x 的值public void setX(int

13、ix)x = ix;/获取成员变量 x 的值public int getX()return x;下面这个程序使用上面这个类,分别声明了一个实参和一个形参。/-文件名 invokeByObject.java,程序编号 3.28-public class invokeByObjectpublic void (onlyTest form)int t = form.getX(); /获取对象 form 的成员变量 x 的值form.setX(t*2); /改变对象 form 的成员变量 x 的值public void onlyTest actual = new onlyTest();actual.se

14、tX(100);System.out.println(“调用 tryChange 方法之前,x=“ + actual.getX() );/测试是否能改变 actual 的成员变量值tryChange(actual);System.out.println(“调用 tryChange 方法之后,x=“ + actual.getX() );public static void main(String args)invokeByObject va = new invokeByObject();va.showDiffer();在程序 3.28 中,showDiffer()先定义一个 actual 对象,

15、并将成员 x 的值置为 100。而后调用方法 tryChange(),它的形参 form 接受 actual 的值,根据图 3.6 所示内容,它们将共用同一个对象。在 tryChange()中改变了 form 的 x值,这一改变,对 actual 也是有效的。程序的输出印证了这一点:调用 tryChange 方法之前,x=100调用 tryChange 方法之后,x=200由于 C+中提供了传值调用和引用调用两种方式,于是有些程序员也认为 Java 的对象参数是采用的引用调用。这其实是一种误解,Java 采用的是传地址值的调用方式,在某些情况下,虽然和引用调用效果相同(比如上例),但在另外一些

16、情形下,还是可以看出两者的区别。下面这个例子说明了这一区别。【例 3.18】 对象传地址值而非引用示例。这里仍然使用例 3.17 中的类 onlyTest,再另外编写一个程序 trySwap。/-文件名 trySwap.java,程序编号 3.29-public class trySwap/企图交换 a 和 b 的值public void swap(onlyTest a, onlyTest b)onlyTest temp;temp = a;a = b;b = temp;/测试能否交换实参的值public void showDiffer()onlyTest ox = new onlyTest()

17、; /创建两个对象onlyTest oy = new onlyTest();ox.setX(100);oy.setX(200);System.out.println(“调用 swap()方法之前的值:“);System.out.println(“ ox.x = “ + ox.getX() + “, oy.x = “ + oy.getX();/测试是否能交换 ox 和 oy 的值swap(ox,oy);System.out.println(“调用 swap()方法之后的值:“);System.out.println(“ ox.x = “ + ox.getX() + “, oy.x = “ + o

18、y.getX();public static void main(String args)trySwap va = new trySwap();va.showDiffer();在方法 swap()中,形参是两个 onlyTest 的对象。如果是引用调用,那么交换这两个对象的值,将对实参 ox 和 oy 产生影响。程序实际运行后输出结果如下:调用 swap()方法之前的值:ox.x = 100, oy.x = 200调用 swap()方法之后的值:ox.x = 100, oy.x = 200从以上输出结果中可以看出,ox 和 oy 的值没有受到丝毫影响,因此它不是引用调用。调用过程可以用图 3.

19、7 和图 3.8 来说明。图 3.7 调用 swap()时的传值过程 图 3.8 执行 swap()之后的情形补充说明一下:若有对象 A 和 B,执行语句:A=B,则 A 和 B 都指向了同一个对象,它们的行为与上述参数传递的行为完全相同。%注意:通过上述分析可以看出,在 Java 中,虽然没有出现显示的指针,也没有指针这个概念,但用普通类声明的变量,本质上和 C/C+中对象指针是一样的。而且,Java 中也没有和 C+中的引用类型完全等效的概念。最后总结一下方法参数的使用情况: 方法不能修改一个基本数据类型的参数; 方法可以改变一个对象参数的状态; 方法不允许让一个对象参数引用一个新的对象。

20、3.5.3 隐含参数 this回顾 3.4.3 小节中的例 3.13,当方法中的局部变量和成员变量同名时,局部变量会屏蔽掉同名的成员变量。为了访问该成员变量,需要使用“this.成员变量”的形式。这个 this 是 Java 定义中的一个关键字。为了让程序员能够在方法中使用 this,Java 会将 this 作为一个隐含的参数传递给每一个实例方法。它其实是指向当前对象的一根指针,直观理解,它就是表示“本对象”的意思。this 作为隐含参数传递,最重要的作用是区分各个对象所拥有的成员。先来回顾 3.5.2 小节程序 3.27 中的类 onlyTest,它拥有一个成员变量 x,两个方法 setX

21、()和 getX()。程序员可以使用这个类来创建若干个对象,这些对象分别拥有自己的成员变量,相互之间不会干扰。如例 3.19 所示。【例 3.19】 使用类 onlyTest 创建多个对象示例。/-文件名 useOnlyTest.java,程序编号 3.30-public class useOnlyTestpublic static void main(String args)onlyTest oa = new onlyTest();onlyTest ob = new onlyTest();oa.setX(100); /将成员变量 x 赋值为 100ob.setX(200); /将成员变量 x

22、 赋值为 200System.out.println( “oa 的成员变量 x= “ + oa.getX() );System.out.println( “ob 的成员变量 x= “ + ob.getX() );程序中分别为两个对象 oa 和 ob 的成员变量赋了不同的值,然后再分别显示它们的值。程序的输出结果如下:oa 的成员变量 x= 100ob 的成员变量 x= 200这个结果完全在预料之中。但如果深入研究一下,还是会存在一些疑问:到底系统是如何来管理这些对象的?显然,不同对象的成员变量一定是单独存放的,那么当它们都调用 setX()方法的时候,这个方法如何知道要为哪一个对象的成员变量

23、x 赋值?一种简单的解决办法,是让每个对象的成员方法也单独存放,并且和成员变量存放在一起,它只处理本对象的成员变量。但这种方法实在是太笨,因为为每个对象存储一套成员方法(而且这些方法的执行语句是完全一样的)需要大量的空间,完全不符合代码重用的原则。所以,所有对象共用一套成员方法显然要经济高效得多。但这样又会带来一个问题,就是这些方法怎样才能区分目前要处理的是哪一个对象的成员变量。解决的答案就是 this 关键字。系统会将 this 指向当前对象,然后作为参数传递给成员方法。在方法访问成员变量时,系统会自动为成员变量加上一个this 作为前缀,这样就可以区分是哪个对象的成员变量。当然,程序员也可

24、以显式地加上 this 做前缀。比如,onlyTest 类与下面这种形式等价:public class onlyTestprivate int x = 0;/设置成员变量 x 的值public void setX(int ix)this.x = ix; /显式地加上 this,表示本对象的变量 x/获取成员变量 x 的值public int getX()return this.x;对于方法:public void setX(int ix)系统会自动加上形参 this,如下:public void setX(onlyTest this, int ix)当通过“oa.setX(100)”来调用方法

25、时,系统生成的是“oa.setX(oa,100)”,这样就很好地解决了区分各个对象成员的问题。3.6 构 造方 法构造方法是类中一种特殊的方法,它一般由系统在创建对象(即类实例化)时自动调用。构造方法是对象中第一个被执行的方法,主要用于申请内存、对类的成员变量进行初始化等操作。构造方法虽然也位于类里面,但在很多情况下与普通成员方法表现不同,所以也有人认为它不是成员方法,而且将其称为“构造器”。本书仍然沿用通常的称呼,将其称为构造方法。构造方法的一般形式为:构造方法名(参数列表)this(参数列表); |super(参数列表);语句序列其中,this 是调用其他的构造方法,super 是调用父类

26、的构造方法。它们都必须放在其他语句的前面。编写式构造方法要注意以下几点: 构造方法的名字必须和类的名字完全相同。 除了访问权修饰符之外,不能有其他任何修饰符,也就不能有返回值。 尽管没有返回值,但并不能用“void”修饰。 构造方法不能用 static 和 final 来修饰。一般也不用 private 修饰,这会导致无法在外部创建对象。 构造方法不能由对象显式地调用。一般通过 new 关键字来调用,或者用 this、super 来调用。 构造方法的参数列表可以为空,也可以有参数。根据参数的有无,可以将构造方法分为无参数的构造方法和带参数的构造方法。 用户定义的类可以拥有多个构造方法,但要求参

27、数列表不同。 如果用户定义的类未提供任何构造方法时,系统会自动为其提供一个无参数的构造方法。3.6.1 无参数构造方法的定义和使用定义一个无参数的构造方法,从语法上来讲很简单,请看下面的示例。【例 3.20】 无参数的构造方法示例。/-文件名 constructNoPara.java,程序编号 3.31-public class constructNoParaprivate int x = 0;/定义一个无参数的构造方法,它必须和类同名public constructNoPara()System.out.println(“这是无参数的构造方法“);x = 100; /为成员变量赋值/获取成员变

28、量 x 的值public int getX()return x;public static void main(String args)constructNoPara oa = new constructNoPara(); /隐式调用无参数的构造方法System.out.println(“x = “ + oa.getX() ); /输出成员变量 x 的值调用构造方法使用的是“new constructNoPara()”,这是一种隐式的调用方法,不能写成“oa.constructNoPara()”的形式。注意到成员变量 x,它在定义的时候已经赋了初值。在构造方法中,先是输出一条信息,然后再次为

29、x 赋值。由于构造方法的执行在定义成员变量之后,它会覆盖掉原来 x 的初值,所以 x 的值为 100。程序的输出结果如下:这是无参数的构造方法x = 100对于初学者而言,最容易犯的错误是在构造方法之前加上“void”,变成下面这个 样子:public class constructNoParaprivate int x = 0;/试图定义一个无参数的构造方法public void constructNoPara() /这里加了一个 voidSystem.out.println(“这是无参数的构造方法“);x = 100; /为成员变量赋值/获取成员变量 x 的值public int getX

30、()return x;public static void main(String args)constructNoPara oa = new constructNoPara(); /隐式调用无参数的构造方法System.out.println(“x = “ + oa.getX() ); /输出成员变量 x 的值这个程序仍然可以通过编译,但运行结果可能会出人意料。它的输出结果如下:x = 0这表明,程序员自己定义的无参数的构造方法根本就没有执行。这是因为加上“void”修饰符之后,constructNoPara()不再是一个构造方法,而成了一个普通方法。语句“constructNoPara o

31、a = new constructNoPara();”并不是调用程序员自己定义的“构造方法”,而是调用了系统提供的默认的无参数的构造方法,这个方法其实什么事情也没做,自然也就不会更改 x 的值。%说明: C+程序员不会犯此类错误。因为在 C+中,如果在构造方法前面加上 void,编译器将报错。%注意:构造方法前的访问权限修饰符同样有 4 种,但通常不会是 private 类型。因为用它来修饰的话,无法在外部使用该构造方法。3.6.2 带参数构造方法的定义和使用在很多时候,需要根据不同的情况为成员变量赋不同的初值,这就需要传递参数给构造方法。因此,Java 中允许定义带参数的构造方法,而且这种带

32、参数的构造方法还可以定义多个(前提是参数列表有区别)这种现象被称为构造方法的重载。Java 规定,如果程序员一个构造方法都不定义,那么系统会自动为其加上一个不带参数的构造方法。如果程序员至少定义了一个构造方法,那么系统不会再提供不带参数的构造方法。当用 new 来创建对象时,需要提供类型相容的参数,否则编译器将报错。【例 3.21】 带参数的构造方法示例。/-文件名 constructWithPara.java,程序编号 3.32-public class constructWithParaprivate int x = 0;/定义一个带参数的构造方法public constructWithP

33、ara(int ix)System.out.println(“这是带参数的构造方法“);x = ix; /为成员变量赋值/获取成员变量 x 的值public int getX()return x;public static void main(String args)constructWithPara oa = new constructWithPara(100); /隐式调用带参数的构造方法System.out.println(“x = “ + oa.getX() );这个程序的流程和程序 3.31 完全一样,只是其中的构造方法多了一个参数而已。程序运行的结果如下:这是带参数的构造方法x =

34、 100这个程序从表面上看没有什么问题,但实际上它存在着一个很大的隐患。如果将类 constructWithPara 提供给其他的程序员使用,使用者很有可能会按照一般的习惯这么来创建一个对象:constructWithPara oa = new constructWithPara();试图使用 x 的默认值。但这样是无法通过编译的,因为系统不会再为 constructWithPara 类提供无参数的构造方法。当此类被其他类继承时,这一问题显得越发严重,它甚至会导致根本无法写出一个子类。因此,强烈建议程序员在定义带参数的构造方法时,也要定义一个不带参数的构造方法,即便这个方法什么事情也不做。所以

35、程序 3.32 应该改成下面这个样子:/-文件名 constructWithPara.java,程序编号 3.33-public class constructWithParaprivate int x = 0;/定义一个带参数的构造方法public constructWithPara(int ix)System.out.println(“这是带参数的构造方法“);x = ix; /为成员变量赋值/定义一个不带参数的构造方法public constructWithPara()/获取成员变量 x 的值public int getX()return x;public static void mai

36、n(String args)constructWithPara oa = new constructWithPara(100); /隐式调用带参数的构造方法System.out.println(“x = “ + oa.getX() );3.6.3 this 关键字和构造方法的调用在 3.5.3 节中,已经介绍了 this 关键字的作用作为隐含参数指向本对象。其实 this 关键字还有一个作用,就是用来显示地调用构造方法。它的使用格式如下:this(参数列表)系统将根据参数列表来决定调用哪一个构造方法。使用 this 时还需注意下面几点: 用 this 调用构造方法时,该语句只能用在构造方法中。

37、 this 语句必须是构造方法中的第一条语句。 和 new 不同,this 虽然可以调用构造方法,但它只是执行构造方法中的语句,并不会创建对象。【例 3.22】 用 this 调用构造方法示例。这里仍然使用程序 3.33,并在无参数的构造方法中加上 this 语句来为 x 赋初值。/-文件名 constructWithPara.java,程序编号 3.34-public class constructWithParaprivate int x = 0;/定义一个带参数的构造方法public constructWithPara(int ix)System.out.println(“这是带参数的构

38、造方法“);x = ix; /为成员变量赋值/定义一个不带参数的构造方法public constructWithPara()this(100); /调用带参数的构造方法为 x 赋值System.out.println(“这是无参数的构造方法“);/获取成员变量 x 的值public int getX()return x;public static void main(String args)constructWithPara oa = new constructWithPara(); /隐式调用无参数的构造方法System.out.println(“x = “ + oa.getX() );在

39、main()方法中利用无参数的构造方法来创建对象,而在无参数的构造方法中,用 this 来调用带参数的构造方法,然后再输出一条信息。程序输出结果如下:这是带参数的构造方法这是无参数的构造方法x = 100在 constructWithPara()方法中,特别注意不要写成下面这个样子:public constructWithPara()System.out.println(“这是无参数的构造方法 “);this(100); /调用带参数的构造方法为 x 赋值这样编译会出错,因为 this 调用构造方法只能作为第一条语句。读者可能会觉得程序 3.34 用 this 调用另外一个构造方法为 x 赋值

40、过于麻烦,不如直接为 x 赋值更简单。当然,这只是一个示例程序,这么做的原因在于:很多情况下,多个构造方法可能会做相同的事情,只是参数有点区别,这就可以将这段相同的代码单独抽取出来成为一个构造方法,然后使用 this 来调用它3.7 静 态 方 法前面已经介绍过,成员变量分为实例变量和静态变量。其中实例变量属于某一个具体的实例,必须在类实例化后才真正存在,不同的对象拥有不同的实例变量。而静态变量被该类所有的对象公有(相当于全局变量),不需要实例化就已经存在。方法也可分为实例方法和静态方法。其中,实例方法必须在类实例化之后通过对象来调用,而静态方法可以在类实例化之前就使用。与成员变量不同的是:无

41、论哪种方法,在内存中只有一份无论该类有多少个实例,都共用同一个方法。本节以前的例子中,除了 main()方法,其余的方法都是实例方法,而 main()则是一个静态方法,所以它才能够被系统直接调用。3.7.1 静态方法的声明和定义定义一个静态方法和定义一个实例方法,在形式上并没有什么区别,只是在声明的头部,需要加上一个关键字 static。它的一般语法形式如下:访问权限修饰符 static 返回值类型 方法名(参数列表 )语句序列例如下面是一个静态的方法:public static void stFun()System.out.println(“这是一个静态方法“);3.7.2 静态方法和实例方

42、法的区别静态方法和实例方法的区别主要体现在两个方面: 在外部调用静态方法时,可以使用“类名.方法名” 的方式,也可以使用“对象名.方法名” 的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。 静态方法在访问本类的成员时,只允许访问静态成员(即静态成员变量和静态方法),而不允许访问实例成员变量和实例方法;实例方法则无此限制。下面几个例子展示了这一区别。【例 3.23】 调用静态方法示例。/-文件名 hasStaticMethod.java,程序编号 3.35-public class hasStaticMethod/定义一个静态方法public static void

43、callMe()System.out.println(“This is a static method.“);下面这个程序使用两种形式来调用静态方法。/-文件名 invokeStaticMethod.java,程序编号 3.36-public class invokeStaticMethodpublic static void main(String args)hasStaticMethod.callMe(); /不创建对象,直接调用静态方法 hasStaticMethod oa = new hasStaticMethod(); /创建一个对象oa.callMe(); /利用对象来调用静态方法

44、程序 3.36 两次调用静态方法,都是允许的,程序的输出如下:This is a static method.This is a static method.允许不创建对象而调用静态方法,是 Java 为了减少程序员调用某些常用方法时的麻烦,而允许程序员按照传统的 C 语言中使用函数的方式来使用方法。典型的例子是前面某些程序中使用“Math.ramdon()”来获取随机数。【例 3.24】 静态方法访问成员变量示例。/-文件名 accessMember.java,程序编号 3.37-class accessMemberprivate static int sa; /定义一个静态成员变量priv

45、ate int ia; /定义一个实例成员变量/下面定义一个静态方法static void statMethod()int i = 0; /正确,可以有自己的局部变量sa = 10; /正确,静态方法可以使用静态变量otherStat(); /正确,可以调用静态方法ia = 20; /错误,不能使用实例变量insMethod(); /错误,不能调用实例方法static void otherStat() /下面定义一个实例方法 void insMethod()int i = 0; /正确,可以有自己的局部变量sa = 15; /正确,可以使用静态变量ia = 30; /正确,可以使用实例变量st

46、atMethod(); /正确,可以调用静态方法本例其实可以概括成一句话:静态方法只能访问静态成员,实例方法可以访问静态和实例成员。之所以不允许静态方法访问实例成员变量,是因为实例成员变量是属于某个对象的,而静态方法在执行时,并不一定存在对象。同样,因为实例方法可以访问实例成员变量,如果允许静态方法调用实例方法,将间接地允许它使用实例成员变量,所以它也不能调用实例方法。基于同样的道理,静态方法中也不能使用关键字 this。main()方法是一个典型的静态方法,它同样遵循一般静态方法的规则,所以它可以由系统在创建对象之前就调用。下面这个程序有个错误,请读者仔细查看。public class ha

47、sErrorint insVar = 100;public static void main(String args)System.out.println(“insVar = “ + insVar);3.7.3 静态代码块在类中,可以将某一块代码声明为静态的,这样的程序块叫静态初始化段。静态代码块的一般形式如下:static 语句序列 静态代码块只能定义在类里面,它独立于任何方法,不能定义在方法里面。 静态代码块里面的变量都是局部变量,只在本块内有效。 静态代码块会在类被加载时自动执行,而无论加载者是 JVM 还是其他的类。 一个类中允许定义多个静态代码块,执行的顺序根据定义的顺序进行。 静态代码块只能访问类的静态成员,而不允许访问实例成员。【例 3.25

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 网络科技 > Java

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报