詳解Java中static關鍵字和內部類的使用
一. static 關鍵字
在Java中,被static修飾的成員,稱之為靜態(tài)成員,也可以稱為類成員,其不屬于某個具體的對象,是所有對象所共享的。
1. static修飾成員變量
static修飾的成員變量,稱為靜態(tài)成員變量
【靜態(tài)成員變量特性】:
- 不屬于某個具體的對象,是類的屬性,所有對象共享的,不存儲在某個對象的空間中
- 既可以通過對象引用訪問(不推薦使用),也可以通過類名訪問,但一般更推薦使用類名訪問
- 類變量存儲在方法區(qū)當中
- 生命周期伴隨類的一生(即:隨類的加載而創(chuàng)建,隨類的卸載而銷毀)
public class Student{
public String name;
public String gender;
public int age;
public double score;
public static String classRoom = "rj2104";
public Student(String name, String gender, int age, double score) {
this.name = name;
this.gender = gender;
this.age = age;
this.score = score;
}
// ...
public static void main(String[] args) {
// 靜態(tài)成員變量可以直接通過類名訪問
System.out.println(Student.classRoom);
Student s1 = new Student("Li leilei", "男", 18, 3.8);
Student s2 = new Student("Han MeiMei", "女", 19, 4.0);
Student s3 = new Student("Jim", "男", 18, 2.6);
// 也可以通過對象訪問:但是classRoom是三個對象共享的
System.out.println(s1.classRoom);
System.out.println(s2.classRoom);
System.out.println(s3.classRoom);
}
}
2. static修飾成員方法
一般類中的數(shù)據(jù)成員都設置為private,而成員方法設置為public,
Java中,被static修飾的成員方法稱為靜態(tài)成員方法,是類的方法,不是某個對象所特有的。
靜態(tài)成員一般是通過靜態(tài)方法來訪問的。
public class Student2{
// ...
private static String classRoom = "rj2104";
// ...
public static String getClassRoom(){
return classRoom;
}
}
class TestStudent {
public static void main(String[] args) {
System.out.println(Student2.getClassRoom());
}
}
【靜態(tài)方法特性】:
- 不屬于某個具體的對象,是類方法
- 可以通過對象調用,也可以通過 類名.靜態(tài)方法名(…) 方式調用,更推薦使用后者
- 不能在靜態(tài)方法中訪問任何非靜態(tài)成員變量和非靜態(tài)成員方法;因為非靜態(tài)方法中默認有this參數(shù),但在靜態(tài)方法中調用時候無法傳遞this引用;除非在靜態(tài)方法中新new一個對象,再通過對象引用去訪問此對象
- 靜態(tài)方法無法重寫,不能用來實現(xiàn)多態(tài)
3. static成員變量的初始化
靜態(tài)成員變量一般不會放在構造方法中來初始化,構造方法中初始化的是與對象相關的實例屬性
靜態(tài)成員變量的初始化分為兩種:就地初始化 和 靜態(tài)代碼塊初始化。
就地初始化:在定義時直接給出初始值
public class Student2{
// ...
//就地初始化
private static String classRoom = "rj2104";
//...
}
用靜態(tài)代碼塊完成初始化
public class Student2{
// ...
private static String classRoom;
//靜態(tài)代碼塊初始化
static {
classRoom = "rj2104";
}
// ...
}
二. 內部類
在 Java 中,可以將一個類定義在另一個類或者一個方法的內部, 前者稱為內部類,后者稱為外部類。內部類也是封裝的一種體現(xiàn)。
內部類和外部類共用同一個java源文件,但是經(jīng)過編譯之后,內部類會形成單獨的字節(jié)碼文件, 一般形成的字節(jié)碼文件文件名為:外部類名字$內部類名字.class

public class OutClass {
class InnerClass{
}
}
// OutClass是外部類
// InnerClass是內部類
根據(jù)內部類定義的位置不同,一般可以分為以下幾種形式:
1.成員內部類(普通內部類)
實例內部類:未被static修飾的成員內部類
靜態(tài)內部類:被static修飾的成員內部類
2.局部內部類
3.匿名內部類
1. 實例內部類
即未被static修飾的成員內部類。
【注意事項】:
- 外部類中的任何成員都可以在實例內部類方法中直接訪問
- 實例內部類當中不能有靜態(tài)的成員變量;非要定義,那么只能是被static final修飾的靜態(tài)常量,常量是在程序編譯的時候就確定的
- 實例內部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束
- 實例內部類對象必須在先有外部類對象前提下才能創(chuàng)建
- 實例內部類的非靜態(tài)方法中默認包含了一個指向外部類對象的引用和一個指向自身實例內部類對象的引用
- 在實例內部類方法中訪問同名的成員時,優(yōu)先訪問自己的,如果要訪問外部類同名的成員,必須:外部類名稱.this.同名成員 來訪問
- 外部類中,不能直接訪問實例內部類中的成員,如果要訪問必須先要創(chuàng)建內部類的對象。
public class OutClass {
private int a;
static int b;
int c;
public void methodA() {
a = 10;
System.out.println(a);
}
public static void methodB() {
System.out.println(b);
}
// 實例內部類:未被static修飾
class InnerClass {
int c;
//實例內部類當中 不能有靜態(tài)的成員變量. 非要定義,那么只能是被static final修飾的
public static final int d = 6;
public void methodInner() {
// 在實例內部類中可以直接訪問外部類中:任意訪問限定符修飾的成員
a = 100;
b = 200;
methodA();
methodB();
System.out.println(d);
// 如果外部類和實例內部類中具有相同名稱成員時,優(yōu)先訪問的是內部類自己的
c = 300;
System.out.println(c);
// 如果要訪問外部類同名成員時候,必須:外部類名稱.this.同名成員名字
OutClass.this.c = 400;
System.out.println(OutClass.this.c);
}
}
public static void main(String[] args) {
// 外部類:對象創(chuàng)建 以及 成員訪問
OutClass outClass = new OutClass();
System.out.println(outClass.a);
System.out.println(outClass.b);
System.out.println(outClass.c);
outClass.methodA();
outClass.methodB();
System.out.println("=============實例內部類的訪問=============");
// 要訪問實例內部類中成員,必須要創(chuàng)建實例內部類的對象
// 而普通內部類定義與外部類成員定義位置相同,因此創(chuàng)建實例內部類對象時必須借助外部類
// 創(chuàng)建實例內部類對象
OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();
innerClass1.methodInner();
// 上述語法比較怪異,也可以先將外部類對象先創(chuàng)建出來,然后再創(chuàng)建實例內部類對象
OutClass.InnerClass innerClass2 = outClass.new InnerClass();
innerClass2.methodInner();
}
}
2. 靜態(tài)內部類
被static修飾的內部成員類稱為靜態(tài)內部類。、
【注意事項】:
在靜態(tài)內部類中只能訪問外部類中的靜態(tài)成員,除非在內部類當中new一個外部類的對象,通過外部類對象的引用去訪問其中的非靜態(tài)成員。
創(chuàng)建靜態(tài)內部類對象時,不需要先創(chuàng)建外部類對象
public class OuterClass2 {
public int data1 = 1;
int data2 = 2;
public static int data3 = 3;
public void test() {
System.out.println("out::test()");
}
// 靜態(tài)內部類:被static修飾的成員內部類
static class InnerClass2 {
public int data4 = 4;
int data5 = 5;
public static int data6 = 6;
public void func() {
System.out.println("out::func()");
//test();
// 編譯失敗,在靜態(tài)內部類中不能直接訪問外部類中的非靜態(tài)成員
//System.out.println(data1);
//System.out.println(data2);
//外部類的非靜態(tài)成員,需要通過外部類的對象的引用才能訪問。
OuterClass2 outerClass = new OuterClass2();
System.out.println(outerClass.data1);
System.out.println(outerClass.data2);
outerClass.test();
// 在靜態(tài)內部類中只能訪問外部類的靜態(tài)成員
System.out.println(data3);
System.out.println(data4);
System.out.println(data5);
System.out.println(data5);
System.out.println(data6);
}
}
public static void main(String[] args) {
// 靜態(tài)內部類對象創(chuàng)建 和 成員訪問
OuterClass2.InnerClass2 innerClass2 = new OuterClass2.InnerClass2();
innerClass2.func();
}
}
3. 局部內部類
定義在外部類的方法體或者{ }中,一般使用的非常少。
【注意事項】
局部內部類只能在所定義的方法體內部使用
不能被public、static等修飾符修飾
局部內部類生成的字節(jié)碼文件稍有區(qū)別:外部類名字$數(shù)字內部類名字.class

ppublic class OutClass {
int a = 10;
public void method(){
int b = 10;
// 局部內部類:定義在方法體內部
// 不能被public、static等訪問限定符修飾
class InnerClass{
public void methodInnerClass(){
System.out.println(a);
System.out.println(b);
}
}
// 只能在該方法體內部使用,其他位置都不能用
InnerClass innerClass = new InnerClass();
innerClass.methodInnerClass();
}
public static void main(String[] args) {
// OutClass.InnerClass innerClass = null; 編譯失敗
}
}4. 匿名內部類
匿名內部類,就是沒有名字的一種嵌套類
匿名內部類形成的字節(jié)碼文件文件名為:外部類名字$數(shù)字.class

4.1 使用匿名內部的好處與演示
在實際開發(fā)中,我們會遇到下面的情況:
一個接口/類的方法的某個執(zhí)行過程在程序中只會執(zhí)行一次,但為了使用它,我們需要創(chuàng)建它的實現(xiàn)類/子類去實現(xiàn)/重寫方法。
代碼中為了這一次的使用去創(chuàng)建一個類,未免太過麻煩,此時就可以使用匿名內部類來解決這個問題
首先來看我們正常的實現(xiàn)邏輯,假設有一個接口,接口當中只有一個方法
public interface Interface {
void show();
}
為了使用該接口的show方法,我們需要去創(chuàng)建一個實現(xiàn)類,重寫show方法的具體實現(xiàn)
public class Test implements Interface{
@Override
public void show() {
System.out.println("只執(zhí)行一次show()");
}
}
public class Main {
public static void main(String[] args) {
Test test = new Test();
test.show();
}
}
如果實現(xiàn)類Test在程序中只使用一次,那么為了這一次的使用去創(chuàng)建一個類太過繁瑣,這種情況下就可以用匿名內部類來實現(xiàn),無需創(chuàng)建新的類,減少代碼冗余,
看下面代碼:
class Main {
public static void main(String[] args) {
//寫法一
Interface in = new Interface() {
@Override
public void show() {
System.out.println("匿名內部類中重寫show()");
}
};
//調用接口方法
in.show();
//寫法二
new Interface() {
@Override
public void show() {
System.out.println("匿名內部類中重寫show()");
}
}.show();//調用接口方法
}
}4.2 匿名內部類的定義格式和使用
定義格式1:
接口名稱 引用名 = new 接口名稱() {
// 覆蓋重寫所有抽象方法
};
引用名.方法調用
定義格式2:
new 接口名稱() {
// 覆蓋重寫所有抽象方法
}.方法調用;
對格式“new 接口名稱() {…}”的理解:
new代表創(chuàng)建一個新的對象對象
接口名稱就是匿名內部類需要實現(xiàn)哪個接口
{…}中是匿名內部類的內容
【注意事項】:
- 匿名內部類,在【創(chuàng)建對象】的時候,只能使用唯一 一次。
- 匿名對象,在【調用方法】的時候,只能調用唯一 一次。
- 匿名內部類是省略了【實現(xiàn)類/子類名稱】,但是匿名對象是省略了【對象名稱】
- 匿名內部類可以用在具體類、抽象類、接口上,且對方法個數(shù)沒有要求。
public class Class {
public void show(String s){
System.out.println("Class::show()");
}
}
public abstract class AbstractClass {
abstract void show(String s);
}
public interface Interface {
void show(String s);
}
public class TestDome {
public static void main(String[] args) {
//重寫普通類的方法
new Class(){
@Override
public void show(String s) {
System.out.println(s);
}
}.show("普通類");
//重寫抽象類的抽象方法
new AbstractClass(){
@Override
void show(String s) {
System.out.println(s);
}
}.show("抽象類");
//實現(xiàn)接口的抽象方法
new Interface(){
@Override
public void show(String s) {
System.out.println(s);
}
}.show("接口");
}
}
執(zhí)行結果:

以上就是詳解Java中static關鍵字和內部類的使用的詳細內容,更多關于Java static關鍵字 內部類的資料請關注腳本之家其它相關文章!
相關文章
java SelectableChannel的使實例用法講解
在本篇文章里小編給大家整理的是一篇關于java SelectableChannel的使實例用法講解內容,有興趣的朋友們可以學習下。2021-03-03
SpringCloud?openfeign聲明式服務調用實現(xiàn)方法介紹
在springcloud中,openfeign是取代了feign作為負載均衡組件的,feign最早是netflix提供的,他是一個輕量級的支持RESTful的http服務調用框架,內置了ribbon,而ribbon可以提供負載均衡機制,因此feign可以作為一個負載均衡的遠程服務調用框架使用2022-12-12
SpringBoot使用Redis對用戶IP進行接口限流的項目實踐
本文主要介紹了SpringBoot使用Redis對用戶IP進行接口限流,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-07-07
Java 實現(xiàn)repalceAll只替換第二個匹配到的字符串
這篇文章主要介紹了Java 實現(xiàn)repalceAll只替換第二個匹配到的字符串,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12
Shiro實現(xiàn)session限制登錄數(shù)量踢人下線功能
這篇文章主要介紹了Shiro實現(xiàn)session限制登錄數(shù)量踢人下線,本文記錄的是shiro采用session作為登錄方案時,對用戶進行限制數(shù)量登錄,以及剔除下線,需要的朋友可以參考下2023-11-11

