目錄
一.String類和常量池
1.String基礎知識
2.常量池
二.內部類
1.概念
2.內部類的作用
3.注意
4.非靜態內部類
5.靜態內部類
6.匿名內部類
7.區域內部類
一.String類和常量池
1.String基礎知識
String數稱作不可變字符序列,
String位于java.lang包中,Java 程式默認匯入java.lang包下的所有類,
Java字串就是Unicode字符序列,例如字串"Java" 就是4個Unicode字符’J'、'a'、'v'、' a'組成的,
Java沒有內置的字串型別,而是在標準Java類別庫中提供了一個預定義的類:
String,每個用雙引號括起來的字串都是String 類的一個實體,
String類的函式對員原字串都沒有影響,都會在原字串的基礎上生成新字串!
toString()方法是列印:類名@物件地址,但是列印字串的時候字串卻是原樣輸出,因為String類重寫了toString()方法,
示例代碼(含有==,equals與去除空格的知識點):
public class string {
public static void main(String[] args) {
String str1="abc";
String str2=new String("abc");
System.out.println(str1==str2);
System.out.println(str1);//會自動呼叫toString()函式,但是String類重寫了
System.out.println(str2);
System.out.println(str1.equals(str2));//比較字串內容時用此函式
System.out.println();
String str3=" a b ";//長度7,前后倆空格,中間一個空格
String str4=str3.trim();//去除頭尾兩端的空格
System.out.println(str4.length());
System.out.println(str4);
//String是不可變字符序列,所有的替換,截取子字串,去空格,轉換大小等都是生成了新字串
System.out.println(str3.replace(" ",""));//去除所有空格
System.out.println(str3);//原字串不變
}
}
輸出:
false
abc
abc
true
3
a b
ab
a b
str1==str2回傳false的原因如下圖:
可見str1的地址是0x1,而str2的地址是0x2,str1==str2比較的又是物件地址,顯然回傳false

2.常量池
在Java的記憶體分析中,我們會經常聽到關于“常量池”的描述,實際上常量池也分了以下三種:
1.全域字串常量池(String Pool)
全域字串常量池中存放的內容是在類加載完成后存到String Pool中的,在每個VM中只有一份,存放的是字串常量的參考值(在堆中生成字串物件實體),
2. class檔案常量池(Class Constant Pool)
class常量池是在編譯的時候每個class都有的,在編譯階段,存放的是常量(文本字串、final 常量等)和符號參考,
3.運行時常量池(Runtime Constant Pool)
運行時常量池是在類加載完成之后,將每個class常量池中的符號參考值轉存到運行時常量池中,
也就是說,每個class都有一個運行時常量池,類在決議之后,將符號參考替換成直接參考,與全域常量池中的參考值保持一致,
二.內部類
1.概念
內部類是一類特殊的類,指的是定義在一個類的內部的類, 實際開發中,為了方便的使用外部類的相關屬性和方法,這時候我們通常會定義一個內部類,
內部類分為成員內部類,匿名內部類,區域內部類;其中成員內部類又分為非靜態內部類和靜態內部類,
一般情況 ,我們把類定義成獨立的單元,有些情況下,我們把一個類放在另一個類的內部定義,稱為內部類(innerclasses),
內部類可以使用public、default、 protected 、private 以及static修飾,而外部頂級類(我們以前接觸的類)只能使用public和default修飾,
2.內部類的作用
內部類提供了更好的封裝,只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問,
內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類的成員, 但外部類不能訪問內部類的內部屬性,
3.注意
內部類只是一個編譯時概念, 一旦我們編譯成功, 就會成為完全不同的兩個類,對于一個名為Outer的外部類和其內部定義的名為Inner的內部類,編譯完成后會出現Outer.class和Outer$Inner.class兩個類的位元組碼檔案,所以內部類是相對獨立的一種存在, 其成員變數/方法名可以和外部類的相同,
右鍵包名,選擇show in Explorer就可查看編譯之后的位元組碼檔案,找一找可看到編譯之后的內部類和外部類生成了如下兩個檔案,

4.非靜態內部類
非靜態內部類(外部類里使用非靜態內部類和平時使用其他類沒什么不同)
1.非靜態內部類物件必須寄存在一 個外部類物件里,因此,如果有一個非靜態內部類物件那么一定存在對應的外部類物件,非靜態內部類物件單獨屬于外部類的某個物件,
2.非靜態內部類可以直接訪問外部類的成員 ,但是外部類不能直接訪問非靜態內部類成員,
3.非靜態內部類不能有靜態方法、靜態屬性和靜態初始化塊,
4.成員變數訪問要點 :
1.內部類里方法的區域變數:變數名,
2.內部類屬性 : this.變數名,
3.外部類屬性 :外部類名.this變數名,
示例代碼1:
//外部類
public class Outer1 {
private int age=10;
private void show(){
System.out.println("要你好看!");
}
//內部類
public class Inner1{
private String name="tom";
private int age=20;
public void showInner(){
System.out.println("Inner.showInner");
System.out.println(age);
//當外部類屬性和內部類屬性發生重名時,可以通過:Outer1.this.成員名 來呼叫
System.out.println(Outer1.this.age);
show();//內部類可以直接使用外部類的成員!
}
}
public static void main(String[] args) {
//創建內部類物件
Outer1.Inner1 inner01=new Outer1().new Inner1();
inner01.showInner();
//下面的定義方式和上面效果一樣
Outer1 out02=new Outer1();
Inner1 inn02=out02.new Inner1();
inn02.showInner();
}
}
輸出:
Inner.showInner
20
10
要你好看!
Inner.showInner
20
10
要你好看!
代碼2:
public class Face {
private String shape="國字臉";
//內部類
class Nose{
private String shape="高鼻梁";
public void breath(){
System.out.println("鼻子長在了"+Face.this.shape+"形狀的臉上");
System.out.println("呼吸,呼吸,呼吸");
}
}
class Ear{
}
class Eye{
}
public static void main(String[] args) {
Face.Nose nose=new Face().new Nose();
nose.breath();
}
}
輸出:
鼻子長在了國字臉形狀的臉上
呼吸,呼吸,呼吸
5.靜態內部類
定義方式:
static class ClassName {
//類體
}
使用要點:
1.靜態內部類可以訪問外部類的靜態成員,不能訪問外部類的普通成員,
2.靜態內部類看做外部類的一個靜態成員,
代碼:
/*
測驗靜態內部類
*/
public class testStaticInnerClass {
public static void main(String[] args) {
//通過new外部類名.內部類名來創建內部類物件
Outer2.Inner2 inner2=new Outer2.Inner2();
inner2.test();
}
}
class Outer2{
private int a=10;
private static int b=20;
//相當于外部類的一個靜態成員
static class Inner2{
public void test(){
//System.out.println(a);//靜態內部類不能訪問外部類的普通屬性
System.out.println(b);//靜態內部類可以訪問外部類的普通屬性
}
}
}
輸出:
20
6.匿名內部類
適合那種只需要使用一次的類,比如:鍵盤監聽操作等等,在安卓開發、awt、 swing開發中常見,
語法:
new 父類構造器(實參類表) \實作介面() {
//匿名內部類類體!
}
代碼:
//匿名內部類
public class TestAnonymousClass {
public void test(A a){
a.run();
}
public static void main(String[] args) {
TestAnonymousClass tac=new TestAnonymousClass();
tac.test(new AA());
tac.test(new A(){
@Override
public void run() {
System.out.println("TestAnonymousClass,run");
}
});
}
}
class AA implements A{
@Override
public void run() {
System.out.println("AA.run");
}
}
interface A{
void run();
}
輸出:
AA.run
TestAnonymousClass.run
7.區域內部類
定義在方法內部的,作用域只限于本方法,稱為區域內部類,
區域內部類的的使用主要是用來解決比較復雜的問題想創建一個類來輔助我們的解決方案,到那時又不希望這個類是公共可用的,所以就產生了區域內部類,
區域內部類和成員內部類一樣被編譯,只是它的作用域發生了改變,它只能在該方法中被使用, 出了該方法就會失效,
區域內部類在實際開發中應用很少,
代碼:
/**
* 測驗區域內部類
*/
public class TestLocalInnerClass {
public void show(){
//作用域僅限于該方法
class Inner3{
public void fun(){
System.out.println("hello world");
}
}
new Inner3().fun();
}
public static void main(String[] args) {
new TestLocalInnerClass().show();
}
}
輸出:
hello world
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/271975.html
標籤:java
