關(guān)鍵字

Advanced Language Features

知識點:一. static修飾符

static修飾符可以用來修飾類的成員變量、成員方法和代碼塊。

. 用static修飾的成員變量表示靜態(tài)變量,可以直接通過類名來訪問;

. 用static修飾的成員方法表示靜態(tài)方法,可以直接通過類名來訪問;

. 用static修飾的程序代碼表示靜態(tài)代碼塊,當Java虛似機加載類時,就會執(zhí)行該代碼塊;

被static所修飾的成員變量和成員方法表明歸某個類所有,它不依賴于類的特定實例,被類的所有實例共享。

1. static 變量

成員變量:定義在類里面、方法外面的變量, 分兩種:

a. 實例變量;

b. 靜態(tài)變量;形式和實例變量類似,在實例變量前面加static關(guān)鍵字;

static變量和實例變量的區(qū)別:

. static變量對于每個類而言在內(nèi)存中只有一個,能被類的所有實例所共享;實例變量對于每個類的每個實例都有一份,它們之間互不影響;

. Java虛擬機在加載類的過程中為static變量分配內(nèi)存,實例變量在加載完類后創(chuàng)建對象時分配內(nèi)存;

. static變量可以直接通過類名訪問,實例變量通過引用類型變量訪問;

舉例: public class Counter {

public int count1 = 0;

public static int count2 = 0;

public static void main(String[] args) {

Counter counterA = new Counter();

Counter counterB = new Counter();

counterA.count1++;

counterA.count2++;

counterB.count1++;

counterB.count2++;

}

}

練習:統(tǒng)計一個類創(chuàng)建實例的個數(shù);

2. static 方法

成員方法分為靜態(tài)方法和實例方法。用static修飾的方法叫靜態(tài)方法,或類方法。靜態(tài)方法也和靜態(tài)變量一樣,不需要創(chuàng)建類的實例,可以直接通過類名來訪問。

public class Sample1 {

public static int add(int x, int y) {

return x+y;

}

}

public class Sample2 {

public void method() {

int result = Sample1.add(1,2);

System.out.println("result= " + result);

}

}

a. static方法可以直接訪問所屬類的實例變量和實例方法,直接訪問所屬類的靜態(tài)變量和靜態(tài)方法;

注:1) 不能使用this關(guān)鍵字;

2) 不能使用super關(guān)鍵字,super關(guān)鍵字用來訪問當前實例從父類中繼承的方法和屬性。super關(guān)鍵字與類的特定實例相關(guān);

3) 靜態(tài)方法必須被實現(xiàn)。靜態(tài)方法用來表示某個類所特有的功能,這種功能的實現(xiàn)不依賴于類的具體實例,也不依賴于它的子類。既然如此,當前類必須為靜態(tài)方法提供實現(xiàn)。

b. 父類的靜態(tài)方法不能被子類覆為非靜態(tài)方法。以下代碼編譯出錯。

public class Base {

public static void method() {}

}

public class Sub extends Base {

public void method() {}//編譯出錯

}

c. 父類的非靜態(tài)方法不能被子類覆蓋為靜態(tài)方法;

3. static 代碼塊

類中可以包含靜態(tài)代碼塊,它不存于任何方法中。在Java虛擬機中加載類時會執(zhí)行這些靜態(tài)代碼塊。如果類中包含多個靜態(tài)代碼塊,那么Java虛擬機將按照它們在類中出現(xiàn)的順序依次執(zhí)行它們,每個靜態(tài)代碼塊只會被執(zhí)行一次。(思考:什么時候JVM對一個類進行類加載)

public class Sample {

static int i = 5;

static {//第一個靜態(tài)代碼塊

System.out.println("First Static code i="+i++);

}

static {//第二個靜態(tài)代碼塊

System.out.println("Second Static code i="+i++);

}

public static void main(String[] args) {

Sample s1 = new Sample();

Sample s2 = new Sample();

System.out.println("At last, i= "+i);

}

}

類的構(gòu)造方法用于初始化類的實例,而類的靜態(tài)代碼塊則可用于初始化類,給類的靜態(tài)變量賦初始值。

靜態(tài)代碼塊與靜態(tài)方法一樣,也不能直接訪問類的實例變量和實例方法,而必須通過實例的引用來訪問它們。

//Student s = new Student();

new一個對象的時候JVM都做了那些事情:

1.之前沒有進行類加載

1.類加載,同時初始化類中靜態(tài)的屬性(賦默認值)

2.執(zhí)行靜態(tài)代碼塊

3.分配內(nèi)存空間,同時初始化非靜態(tài)的屬性(賦默認值)

4.調(diào)用父類構(gòu)造器

5.父類構(gòu)造器執(zhí)行完后,如果自己聲明屬性的同時有顯示的賦值,那么進行顯示賦值把默認值覆蓋

6.執(zhí)行匿名代碼塊

7.執(zhí)行構(gòu)造器

8.返回內(nèi)存地址

例子:

package com.briup.ch06;

public class Test {

public static void main(String[] args) {

A a = new B();

}

}

class A{

protected String name = "lisi";

public A() {

System.out.println("父類構(gòu)造器A");

System.out.println("父類構(gòu)造器A中調(diào)用test方法開始,由于子類重寫過test方法所以這里執(zhí)行子類的test方法");

test();

System.out.println("父類構(gòu)造器A中調(diào)用test方法結(jié)束");

}

public void test(){

}

}

class B extends A{

private String name = "tom";

{

System.out.println("子類匿名代碼塊中:"+name);

}

public B() {

System.out.println("子類構(gòu)造器B");

}

public void test(){

System.out.println("test方法中:this.name="+this.name);

System.out.println("test方法中:super.name="+super.name);

}

}

打印結(jié)果:

父類構(gòu)造器A? ? ? ? ? ? ? ? ? ? ? ? ? ? //子類構(gòu)造器調(diào)用父類構(gòu)造器

父類構(gòu)造器A中調(diào)用test方法開始,由于子類重寫過test方法所以這里執(zhí)行子類的test方法

test方法中:this.name=null? ? //這個時候父類構(gòu)造器還沒有執(zhí)行完 所以子類中的屬性不會顯示賦值 所以只有初始的默認值null

test方法中:super.name=lisi? //這個時候父類構(gòu)造器開始調(diào)用 了 所以父類中的屬性已經(jīng)有了顯示賦的值了

父類構(gòu)造器A中調(diào)用test方法結(jié)束

子類匿名代碼塊中:tom? ? ? ? ? //這個時候父類構(gòu)造器已經(jīng)調(diào)用結(jié)束 所以子類中的屬性已經(jīng)有了顯示賦的值了

子類構(gòu)造器B

結(jié)論:? 子類中的屬性的顯示賦值的時機 是在 父類構(gòu)造器執(zhí)行完之后和子類的匿名代碼塊執(zhí)行之前的某個時候

2.之前已經(jīng)進行了類加載

1.分配內(nèi)存空間,同時初始化非靜態(tài)的屬性(賦默認值)

2.調(diào)用父類構(gòu)造器

3.父類構(gòu)造器執(zhí)行完后,如果自己聲明屬性的同時有顯示的賦值,那么進行顯示賦值把默認值覆蓋

4.執(zhí)行匿名代碼塊

5.執(zhí)行構(gòu)造器

6.返回內(nèi)存地址

練習例子:StaticTest.java? StaticTest2.java

4. 靜態(tài)導入

靜態(tài)導入也是JDK5.0引入的新特性。

要使用靜態(tài)成員(方法和變量)我們必須給出提供這個靜態(tài)成員的類。使用靜態(tài)導入可以使被導入類的靜態(tài)變量和靜態(tài)方法在當前類中可以直接使用,使用這些靜態(tài)成員無需再在前面寫上他們所屬的類名。

//例如:

import static java.lang.Math.random;

import static java.lang.Math.PI;;

public class Test {

public static void main(String[] args) {

//之前是需要Math.random()調(diào)用的

System.out.println(random());

System.out.println(PI);

}

}

二. final修改符

final具有"不可改變的"含義,它可以修飾非抽象類、非抽象成員方法和變量。

. 用final修飾的類不能被繼承,沒有子類;

. 用final修飾的方法不能被子類的方法覆蓋;

. 用final修飾的變量表示常量,只能被賦一次值;

final不能用來修飾構(gòu)造方法,因為"方法覆蓋"這一概念僅適用于類的成員方法,而不適用于類的構(gòu)造方法,父類的構(gòu)造方法和子類的構(gòu)造方法之間不存在覆蓋關(guān)系. 因此用final修飾構(gòu)造方法是無意義的。父類中用private修飾的方法不能被子類的方法覆蓋,因此private類型的方法默認是final類型的。

1. final類

繼承關(guān)系的弱點是打破封裝,子類能夠訪問父類的方法,而且能以方法覆蓋的方式修改實現(xiàn)細節(jié)。在以下情況下,

可以考慮把類定義為final類型,使得這個類不能被繼承。

. 子類有可能會錯誤地修改父類的實現(xiàn)細節(jié);

. 出于安全,類的實現(xiàn)細節(jié)不允許有任何改動;

. 在創(chuàng)建對象模型時,確信這個類不會再被擴展;

例如JDK中java.lang.String類被定義為final類型;

2. final方法;

某些情況下,出于安全原因,父類不允許子類覆蓋某個方法, 此時可以把這個方法聲明為final類型。例如在

java.lang.Object類中,getClass()方法為final類型。

3. final變量:

final修飾的屬性(成員變量)賦值的位置:

非靜態(tài)的成員變量

1.聲明的同時

2.匿名代碼塊

3.構(gòu)造器(類中出現(xiàn)的所有構(gòu)造器)

靜態(tài)的成員變量

1.聲明的同時

2.static代碼塊

a. final可以修飾靜態(tài)變量、實例變量、局部變量;

b. final變量都必須顯示初始化,否則會導致編譯錯誤;

1) 靜態(tài)變量,定義變量時進行初始化或者static代碼塊中賦值;

2) 實例變量,可以在定義變量時,或者在構(gòu)造方法中進行初始化;

c. final變量只能賦一次值。

public class Sample {

private final int var1 = 1;

public Sample() {

var1 = 2;? ? ? ? ? ? ? ? //編譯出錯,不允許改變var1實例變量的值;

}

public void method(final int param) {

final int var2 = 1;

var2++;? ? ? ? ? ? ? ? ? //編譯出錯,不允許改變var2局部常量的值

param++;? ? ? ? ? ? ? ? //編譯出錯,不允許改變final類型參數(shù)的值;

}

}

public class Sample {

final int var1;? ? ? ? ? ? ? //定義var1實例常量

final int var2 = 0;? ? ? ? ? //定義并初始化var2實例常量

Sample() {

var1 = 1;? ? ? ? ? ? ? //初始化var1實例常量

}

Sample(int x) {

var1 = x;? ? ? ? ? ? ? ? //初始化var1實例常量

}

}

練習 FinalTest.java

三. abstract修飾符

可用來修飾類和成員方法。

. 用abstract修飾的類表示抽象類,抽象類不能實例化,即不允許創(chuàng)建抽象類本身的實例。沒有用abstract修飾的類稱為具體類,具體類可以被實例化。

. 用abstract修飾的方法表示抽象方法,抽象方法沒有方法體。抽象方法用來描述系統(tǒng)具有什么功能,但不提供具體的實現(xiàn)。

沒有abstract修飾的方法稱為具體方法,具體方法具有方法體。

語法規(guī)則;

1) 抽象類中可以沒有抽象方法,但包含了抽象方法的類必須被定義為抽象類;

2) 沒有抽象構(gòu)造方法,也沒有抽象靜態(tài)方法;

3) 抽象類中可以有非抽象的構(gòu)造方法;

4) 抽象類及抽象方法不能被final修飾符修飾。

抽象類不允許實例化:思考原因?

練習 AbstractTest.java

四. 接口

接口使用的目的:解決多重繼承問題;例如Fish類繼承Animal類,表明Fish是一種動物,但魚同樣也是一種食物,如何表示這種關(guān)系呢? 由于Java語言不支持一個類有多個直接的父類,因此無法用繼承關(guān)系來描述魚既是一種食物,又是一種動物,為了解決這一問題,Java語言引入接口類型,簡稱接口。一個類只能有一個直接的父類,但是可以實現(xiàn)多個接口。 采用這種方式,Java語言對多繼承提供了有力的支持。

1. 接口是抽象類的另外一種形式

抽象類抽象到極致就是接口,抽象類可存在有方法體的方法,接口中的方法全部為抽象方法;

2. 接口中的所有方法均是抽象方法, 默認都是public、abstract類型的;

public interface A {

void method1();? ? ? ? ? ? ? ? //合法,默認為public、abstract類型

public abstract void method2();//合法,顯示聲明為public、abstract類型

3. 接口中的成員變量默認都是public, static, final類型,必須被顯式初始化;

public interface A {

int CONST = 1;? ? ? ? ? ? ? ? //合法,CONST默認為public, static, final類型

public static final int OPAQUE = 1;? //合法,顯示聲明為public static final 類型

}

4. 接口中只能包含public, static, final類型成員變量和public、abstract類型的成員方法;

5. 接口中沒有構(gòu)造方法,不能被實例化。

6. 一個類只能繼承一個直接的父類,但能實現(xiàn)多個接口。

抽象類和接口比較:

1. 相同點:

a. 都不能被實例化;

b. 都能包含抽象方法;

2. 不同點;

a. 抽象類中可以為部分方法提供默認的實現(xiàn),從而避免子類中重復(fù)實現(xiàn)它們,提高代碼的可重用性,而接口中只能包含抽象方法;

b. 一個類只能繼承一個直接的父類,這個父類有可能是抽象類;但一個類可以實現(xiàn)多個接口,這是接口的優(yōu)勢所在。

練習:InterfaceTest.java InterfaceTest2.java

五. 訪問控制

面向?qū)ο蟮幕舅枷胫皇欠庋b實現(xiàn)細節(jié)并且公開方法。Java語言采用訪問控制修飾符來控制類及類的方法和變量的訪問

權(quán)限,從而只向使用者暴露方法,但隱藏實現(xiàn)細節(jié)。訪問控制分4種級別。

訪問級別? ? ? 訪問控制修飾符? ? ? ? 同類? ? ? 同包? ? ? 子類? ? ? 不同的包

公開級別:? ? ? public? ? ? ? ? ? ? ? y? ? ? ? y? ? ? ? ? y? ? ? ? ? y

受保護? ? ? ? ? protected? ? ? ? ? ? y? ? ? ? ? y? ? ? ? ? y

默認? ? ? ? ? 沒有訪問控制符? ? ? ? ? y? ? ? ? ? y

私有? ? ? ? ? ? private? ? ? ? ? ? ? ? y

成員變量、成員方法和構(gòu)造方法可以處于4個訪問級別中的一個;

頂層類只可以處于公開或默認訪問級別;

注意:protected和default都有包訪問權(quán)限(同包下可以訪問)

六. 內(nèi)部類

在一個類的內(nèi)部定義的類稱為內(nèi)部類。

內(nèi)部類分為:

成員內(nèi)部類 靜態(tài)內(nèi)部類 局部內(nèi)部類 匿名內(nèi)部類

頂層類(正常類)只能處于public和默認訪問級別,而成員內(nèi)部類可以處于public, protected, private和默認這4種訪問級別;

1.? 靜態(tài)內(nèi)部類;

例子:StaticOutterClass.java

是成員內(nèi)部類的一種,用static修飾。靜態(tài)內(nèi)部類具有以下特點:

1)? 靜態(tài)內(nèi)部類:(相對應(yīng)類中的一個靜態(tài)變量)

靜態(tài)內(nèi)部類中訪問不到外部類的非靜態(tài)屬性或者方法

靜態(tài)內(nèi)部類的對象不需要依賴于外部類的對象

內(nèi)部類 變量名字 = new 內(nèi)部類();

public class A {

public static class B{

private int v;

public void say(){

System.out.println("hello");

}

}

public static void main(String[] args){

B b = new B();

}

}

2) 靜態(tài)內(nèi)部類可以直接訪問外部類的靜態(tài)成員,如果訪問外部類的實例成員,就必須通過外部類的實例去訪問。

class A {

private int a1;? ? ? ? ? ? ? //實例變量a1

private static int a2;? ? ? //靜態(tài)變量a2

public static class B {

int b1 = a1;? ? ? ? ? //編譯錯誤,不能直接訪問外部類A的實例變量a1

int b2 = a2;? ? ? ? ? //合法,可以直接訪問外部類A的靜態(tài)變量a2

int b3 = A.this.a1;? //不合法 靜態(tài)內(nèi)部類中不能訪問外部對象的this

}

}

3) 在靜態(tài)內(nèi)部類中可以定義靜態(tài)成員和實例成員。

class A {

public static class B {

int v1;? ? ? ? ? ? ? ? ? ? ? //實例變量

static int v2;? ? ? ? ? ? ? ? //靜態(tài)變量

public static class C {

static int v3;? ? ? ? //靜態(tài)內(nèi)部類

}

}

}

4) 可以通過完整的類名直接訪問靜態(tài)內(nèi)部類的靜態(tài)成員。

class A {

public static class B {

int v1;? ? ? ? ? ? ? ? ? ? ? //實例變量

static int v2;? ? ? ? ? ? ? ? //靜態(tài)變量

public static class C {

static int v3;? ? ? ? //靜態(tài)內(nèi)部類

int v4;

}

}

}

public class Tester {

public void test() {

A.B b = new A.B();

A.B.C c = new A.B.C();

b.v1 = 1;

v.v2 = 1;

A.B.v1 = 1;? ? ? ? ? ? //編譯錯誤

A.B.v2 = 1;? ? ? ? ? ? //合法

A.B.C.v3 = 1;? ? ? ? ? //合法

}

}

2.? 成員內(nèi)部類:(相當于類中的一個成員變量)

成員內(nèi)部類中不能有static的聲明屬性或者方法

成員內(nèi)部類可以由public protected default private修飾

成員內(nèi)部類是依賴于外部類的對象而存在的

外部類.內(nèi)部類 var = new 外部類().內(nèi)部類();

例子:InstanceOutterClass.java

1) 在創(chuàng)建實例內(nèi)部類的實例時,外部類的實例必須已經(jīng)存在。

Outer.InnerTool tool = new Outer().new InnerTool();

等價于:

Outer outer = new Outer();

Outer.InnerTool tool = outer.new InnerTool();

以下代碼會導致編譯錯誤:

Outer.InnerTool tool = new Outer.InnerTool();

2) 實例內(nèi)部類的實例自動持有外部類的實例的引用。在內(nèi)部類中, 可以直接訪問外部類的所有成員,包括

成員變量和成員方法。

public class A {

private int a1;

public int a1;

static int a1;

public A(int a1, int a2) {

this.a1 = a1;

this.a2 = a2;

}

protected int methodA() {

return a1*a2;

}

class B {

int b1 = a1;? ? ? ? ? ? ? //直接訪問private的a1

int b2 = a2;? ? ? ? ? ? ? //直接訪問public的a2

int b3 = a3;? ? ? ? ? ? ? //直接訪問static的a3

int b4 = A.this.a1;? ? //訪問類A的當前實例中的a1

int b5 = methodA();? ? ? ? //訪問methodA()方法

}

public static void main(String args[]) {

A.B b = new A(1,2).new B();

System.out.println("b.b1="+b.b1);? ? //打印b.b1=1;

System.out.println("b.b2="+b.b2);? ? //打印b.b2=2;

System.out.println("b.b3="+b.b3);? ? //打印b.b3=0;

System.out.println("b.b4="+b.b4);? ? //打印b.b4=3;

System.out.println("b.b5="+b.b5);? ? //打印b.b5=2;

}

}

3) 外部類實例與內(nèi)部類實例之間是一對多的關(guān)系,一個內(nèi)部類實例只會引用一個外部類實例,而一個外部類實例對應(yīng)零個或多個內(nèi)部類實例。在外部類中不能直接訪問內(nèi)部類的成員,必須通過內(nèi)部類的實例去訪問。

class A {

class B {

private int b1 = 1;

public int b2 = 2;

class C{}

}

public void test() {

int v1 = b1;? ? ? ? ? ? ? ? ? ? ? ? ? //invalid

int v2 = b2;? ? ? ? ? ? ? ? ? ? ? ? ? //invalid

B.C c1 = new C();? ? ? ? ? ? ? ? ? ? //invalid

B b = new B(); //valid

int v3 = b.b1;? ? ? ? ? ? ? ? ? ? ? ? ? //valid

int v4 = b.b2;? ? ? ? ? ? ? ? ? ? ? ? ? //valid

B.C c2 = b.new C();? ? ? ? ? ? ? ? ? ? //valid

B.C c3 = new B().new C();? ? ? ? ? ? ? //valid

}

}

4) 實例內(nèi)部類中不能定義靜態(tài)成員,而只能定義實例成員。

5) 如果實例內(nèi)部類B與外部類A包含同名的成員,那么在類B中, this.v表示類B的成員, A.this.v表示類A的成員。

3.? 局部內(nèi)部類:(相當于一個方法中的局部變量)

局部內(nèi)部類不能用public private等修飾符修飾

寫在方法當中,而且只能在方法當中使用

可以訪問外層類的普通成員變量和靜態(tài)成員變量以及普通方法和靜態(tài)方法,也可以訪問該內(nèi)部類所在方法當中的局部變量,但是這個局部變量必須是final修飾;

例子:LocalOutterClass.java

1) 局部內(nèi)部類只能在當前方法中使用。

class A {

B b = new B();? ? ? ? ? ? ? ? //編譯錯誤;

public void method() {

class B{

int v1;

int v2;

class C {

int v3;

}

}

B b = new B();? ? ? ? ? ? ? ? //合法

B.C c = b.new C();? ? ? ? ? ? //合法

}

}

2) 局部內(nèi)部類和實例內(nèi)部類一樣,不能包含靜態(tài)成員。

class A {

public void method() {

class B{

static int v1;? ? ? ? ? //編譯錯誤

int v2;? ? ? ? ? ? ? ? ? //合法

static class C {? ? ? ? //編譯錯誤

int v3;

}

}

}

}

3) 在局部內(nèi)部類中定義的內(nèi)部類也不能被public、protected和private這些訪問控制修飾符修飾;

4) 局部內(nèi)部類和實例內(nèi)部類一樣,可以訪問外部類的所有成員,此外,局部內(nèi)部類還可以訪問所在方法中的final類型

的參數(shù)和變量。

4.匿名內(nèi)部類:(和局部內(nèi)部類很相似)

匿名內(nèi)部類也是用的最多的內(nèi)部類

可以寫成成員變量的形式,也可以寫在方法當中,一般寫在方法當中較多

匿名內(nèi)部類里可以訪問外部類的普通屬性和方法,已經(jīng)靜態(tài)屬性和方法,如果要訪問這個內(nèi)部類所在方法中的局部變量,那么要求這個局部變量必須是final修飾的

匿名內(nèi)部類里面沒有構(gòu)造函數(shù),因為這個類沒有名字,所以在其他地方不能用

例子:AnonymousOutterClass.java

public class Hello{

public void test(){

//假如A是同包下的一個接口,有一個抽象方法go

A a = new A(){

public void go(){

System.out.println("gogogo");

}

};

}

}

幾種內(nèi)部類的區(qū)別:

1. 創(chuàng)建

a. 聲明的位置:

靜態(tài)內(nèi)部類:類的內(nèi)部,方法的外部,用static關(guān)鍵字修飾;

實例內(nèi)部類:類的內(nèi)部,方法的外部,不用static關(guān)鍵字修飾;

局部內(nèi)部類:方法的內(nèi)部;

匿名內(nèi)部類:既可以在類的內(nèi)部,方法的外部,也可以在方法的內(nèi)部;

b. 實例化方式:

靜態(tài)內(nèi)部類:new Outer.Inner();? ? ? ? ? //在外部類外創(chuàng)建;

new Inner();? ? ? ? ? ? ? ? //在外部類內(nèi)內(nèi)部類外創(chuàng)建

實例內(nèi)部類:new Outer().new Inner();? ? ? //在外部類外創(chuàng)建;

this.new Inner();? ? ? ? ? ? //在外部類內(nèi)內(nèi)部類外創(chuàng)建

局部內(nèi)部類:new Inner();? ? ? ? ? ? ? ? ? //只能在方法內(nèi)部創(chuàng)建;

匿名內(nèi)部類:new 類名() {};

2. 訪問

a. 外部類訪問內(nèi)部類:

靜態(tài)內(nèi)部類:通過完整的類名直接訪問靜態(tài)內(nèi)部類的靜態(tài)成員;

實例內(nèi)部類:通過內(nèi)部類的實例去訪問內(nèi)部類的成員;

局部內(nèi)部類:不能訪問;

匿名內(nèi)部類:不能訪問;

b. 內(nèi)部類訪問外部類:

靜態(tài)內(nèi)部類:直接訪問外部類的靜態(tài)成員;

實例內(nèi)部類:可以直接訪問外部類的所有成員;

如果實例內(nèi)部類B與外部類A包含同名的成員,那么在類B中, this.v表示類B的成員,

A.this.v表示類A的成員。

局部內(nèi)部類:可以直接訪問外部類的所有成員, 訪問所在方法中的final類型的參數(shù)和變量;

匿名內(nèi)部類:可以直接訪問外部類的所有成員, 訪問所在方法中的final類型的參數(shù)和變量;

七. ==? 和 equals() 的區(qū)別

== :比較的是,值是不是相等

基本數(shù)據(jù)類型比較的是值,引用類型比較的是地址值

equals(Object o): Object類中的方法,所以,在每一個java類中,都會有這個方法,因為每一個java類都是直接或者間接的Object類的子類,會繼承到這個方法

如果自己所寫的類中已經(jīng)重寫了equals方法,那么就安裝用戶自定義的方式來比較倆個對象是否相等,如果沒有重寫過equal方法,那么會調(diào)用父類(Object)中的equals方法進行比較,也就是比較地址值

注意:equals(Object o)方法只能是一個對象來調(diào)用,然后參數(shù)也是要傳一個對象的

所以下面是錯誤的寫法:

int a = 1;

a.equals(1);

因為基本數(shù)據(jù)類型不是算是對象,不能調(diào)用方法

如果是基本數(shù)據(jù)類型那么就用==比較

如果是引用類型的話,想按照自己的方式去比較,就要重寫這個類中的equals方法, 如果沒有重寫,那么equals和==比較的效果是一樣的,都是比較引用的地址值

如果是比較字符串,那么直接用equals就可以了,因為String類里面已經(jīng)重寫了equals方法,比較的時候字符串的內(nèi)容,而不是引用的地址值了

toString(): Object類中的方法,所以,在每一個java類中,都會有這個方法,因為每一個java類都是直接或者間接的Object類的子類,會繼承到這個方法

當前用一個引用指向一個對象的時候,比如:Student s = new Student(),然后如果直接打印這個引用s,其實是調(diào)用了s.toString()方法,然后就會把這個引用里面的存放的堆區(qū)對象的地址值顯示出來

所以我們會常常在類中重寫這個toString()方法,然后讓這個類的引用按照我們要求來返回內(nèi)容。

getClass():Object類中的方法,所以,在每一個java類中,都會有這個方法,并且這個方式final修飾的,不能被子類重寫,這個方法可以返回某一個引用在運行的時候指向?qū)ο蟮念愋?/p>

例如:Person p = new Student()

//會輸出:class com.briup.chap06.Student

//說明這個引用p在運行時指向的是Student這個類的對象

//注意這個引用p的類型是Person的(多態(tài))

System.out.println(p.getClass());

八. 基本數(shù)據(jù)類型對應(yīng)的包裝類型

boolean Boolean

byte Byte

short Short

char Character

int Integer

long Long

float Float

double Double

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • C++關(guān)鍵字的思考 本章內(nèi)容:1 關(guān)鍵字的相關(guān)理解1.1 const關(guān)鍵字1.2 static關(guān)鍵字1.3 非局部...
    Haley_2013閱讀 852評論 0 49
  • 文章大綱:1.為什么static會有這樣的效果?2.static的使用3.static誤區(qū)4.static面試題 ...
    檸檬烏冬面閱讀 5,982評論 3 43
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,502評論 19 139
  • 我們經(jīng)常碰到一些情況: 搬家換城市等,或以前固定的理發(fā)師搬走等,需要更換理發(fā)師。然而,每次換理發(fā)師就像買彩票一樣,...
    寶貝安心睡閱讀 798評論 0 0

友情鏈接更多精彩內(nèi)容