前言:
我們上一篇講到了this,super和代碼塊,這一篇我們聊一下static final,文章中每一條概念都會配上示範代碼和代碼截圖還有結果,希望能給兄弟們帶來幫助!
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwVZnFWbp1zczV2YvJHctM3cv1Ces0zaHRGcWdUYuVzVa9GczoVdG1mWfVGc5RHLwIzX39GZhh2csATMflHLwEzX4xSZz91ZsAzMfRHLGZkRGZkRfJ3bs92YskmNhVTYykVNQJVMRhXVEF1X0hXZ0xCNx8VZ6l2cssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1E2NlVTNhNjMjFWN4MGOllDNzQGMzMmNzgzN1YDMyQTOiRmN1gzLchDMyIDMy8CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
一.介紹
static修飾的成員變量和成員方法獨立于該類的任何對象。也就是說,它不依賴類特定的執行個體,被類的所有執行個體共享。
隻要這個類被加載,Java虛拟機就能根據類名在運作時資料區的方法區内定找到他們。是以,static對象可以在它的任何對象建立之前通路,無需引用任何對象。
final是java中的一個關鍵字,可以用來修飾變量、方法和類。用關鍵詞final修飾的域成為最終域。用關鍵詞final修飾的變量一旦指派,就不能改變,也稱為修飾的辨別為常量。如果一個類的域被關鍵字final所修飾,它的取值在程式的整個執行過程中将不會改變。
假如說整個類都是final,就表明自己不希望從這個類繼承,或者不答應其他任何人采取這種操作。換言之,出于這樣或那樣的原因,我們的類肯定不需要進行任何改變;或者出于安全方面的理由,我們不希望進行子類化(子類處理)。
除此以外,我們或許還考慮到執行效率的問題,并想確定涉及這個類各對象的所有行動都要盡可能地有效。
二.知識點介紹
1、static
2、final
3、static和final一起使用
三.節點詳解
1、static
1.1、修飾成員變量
在我們平時的使用當中,static最常用的功能就是修飾類的屬性和方法,讓他們成為類的成員屬性和方法,我們通常将用static修飾的成員稱為類成員或者靜态成員,這句話挺起來都點奇怪,其實這是相對于對象的屬性和方法來說的。
代碼示範:
package com.Test;
public class Person {
String name;
int age;
/*自定義的toString()方法不能夠傳入參數,并且必須傳回一個字元串。定義的toString可以傳回我們任何需要的值*/
public String toString() {
return "Name:" + name +
", Age:" + age;
}
public static void main(String[] args) {
//對象一
Person p1 = new Person();
p1.name = "磊哥";
p1.age = 25;
//對象二
Person p2 = new Person();
p2.name = "java曆險記";
p2.age = 4;
System.out.println(p1);
System.out.println(p2);
}
}
1.2、修飾成員方法
static的另一個作用,就是修飾成員方法。相比于修飾成員屬性,修飾成員方法對于資料的存儲上面并沒有多大的變化,因為我們從上面可以看出,方法本來就是存放在類的定義當中的。static修飾成員方法最大的作用,就是可以使用"類名.方法名"的方式操作方法,避免了先要new出對象的繁瑣和資源消耗,我們可能會經常在幫助類中看到它的使用:
代碼示範:
package com.Test;
public class Person {
public static void print(Object o){
System.out.println(o);
}
public static void main(String[] args) {
Person.print("磊哥的java曆險記");
}
}
1.3、靜态塊
在說明static關鍵字的第三個用法時,我們有必要重新梳理一下一個對象的初始化過程。以下面的代碼為例:
代碼示範:
package com.Test;
public class Person {
}
class Book{
public Book(String msg) {
System.out.println(msg);
}
}
class PersonTwo {
Book book1 = new Book("book1成員變量初始化");
static Book book2 = new Book("static成員book2成員變量初始化");
public PersonTwo(String msg) {
System.out.println(msg);
}
Book book3 = new Book("book3成員變量初始化");
static Book book4 = new Book("static成員book4成員變量初始化");
public static void main(String[] args) {
PersonTwo p1 = new PersonTwo("p1初始化");
}
}
1.4、靜态導包
相比于上面的三種用途,第四種用途可能了解的人就比較少了,但是實際上它很簡單,而且在調用類方法時會更友善。以上面的“PrintHelper”的例子為例,做一下稍微的變化,即可使用靜态導包帶給我們的友善:
代碼示範:
/*
PrintHelper.java檔案
*/
package com.Test;
public class PrintHelper {
public static void print(Object o){
System.out.println(o);
}
}
package com.Test;
import static com.Test.PrintHelper.print;
public class Main {
public static void main(String[] args) {
print("磊哥的java曆險記");
}
}
2、final
在java中,final的含義在不同的場景下有細微的差别,但總體上來說,它指的是“這是不可變的”。下面,我們來講final的四種主要用法。
2.1、修飾資料
在編寫程式時,我們經常需要說明一個資料是不可變的,我們成為常量。在java中,用final關鍵字修飾的變量,隻能進行一次指派操作,并且在生存期内不可以改變它的值。更重要的是,final會告訴編譯器,這個資料是不會修改的,那麼編譯器就可能會在編譯時期就對該資料進行替換甚至執行計算,這樣可以對我們的程式起到一點優化。不過在針對基本類型和引用類型時,final關鍵字的效果存在細微差别。舉個例子:
代碼示範:
package com.Test;
public class PrintHelper {
static class Value {
int v;
public Value(int v) {
this.v = v;
}
}
public static class FinalTest {
final int f1 = 1;
final int f2;
public FinalTest() {
f2 = 2;
}
public static void main(String[] args) {
final int value1 = 1;
// value1 = 4;
final double value2;
value2 = 2.0;
final Value value3 = new Value(1);
value3.v = 4;
}
}
}
2.2、修飾方法參數
前面我們可以看到,如果變量是我們自己建立的,那麼使用final修飾表示我們隻會給它指派一次且不會改變變量的值。那麼如果變量是作為參數傳入的,我們怎麼保證它的值不會改變呢?這就用到了final的第二種用法,即在我們編寫方法時,可以在參數前面添加final關鍵字,它表示在整個方法中,我們不會(實際上是不能)改變參數的值:
代碼示範:
package com.Test;
public class Main {
public void finalFunc(final int i, final PrintHelper p) {
// i = 5; 不能改變i的值
// v = new Value(); 不能改變v的值
p.name = "磊哥的java曆險記"; // 可以改變引用對象的值
}
}
class Test4 {
public static void main(String[] args) {
new Test4().f1(2);
}
public void f1(final int i) {
//i++; //i是final類型的,值不允許改變的.
System.out.print(i);
}
}
2.3、修飾方法
第三種方式,即用final關鍵字修飾方法,它表示該方法不能被覆寫。這種使用方式主要是從設計的角度考慮,即明确告訴其他可能會繼承該類的程式員,不希望他們去覆寫這個方法。這種方式我們很容易了解,然而,關于private和final關鍵字還有一點聯系,這就是類中所有的private方法都隐式地指定為是final的,由于無法在類外使用private方法,是以也就無法覆寫它。
代碼示範:
class A{
public
final void a(){
}
}
class A1 extends A{
public final void a(){//不可以
}
}
代碼示範:
package com.Test;
public class Test {
public static void main(String[] args) {
//TODO 自動生成方法存根
}
public void f1() {
System.out.println("f1");
}
//無法被子類覆寫的方法
public final void f2() {
System.out.println("f2");
}
public void f3() {
System.out.println("f3");
}
private void f4() {
System.out.println("f4");
}
}
//繼承Test
class Test2 extends Test {
public void f1(){
System.out.println("Test父類方法f1被覆寫!");
}
/*public void f2(){
System.out.println("Test父類方法不能被f2被覆寫!");
}*/
public void f3(){
System.out.println("Test父類方法f3被覆寫!");
}
public static void main(String[] args) {
Test2 t=new Test2();
t.f1();
//調用從父類繼承過來的final方法
t.f2();
//調用從父類繼承過來的方法
t.f3();
//調用失敗,無法從父類繼承獲得
//t.f4();
}
}
2.4、修飾類
了解了final關鍵字的其他用法,我們很容易可以想到使用final關鍵字修飾類的作用,那就是用final修飾的類是無法被繼承的。
final class A{
}
3、static和final一起使用
(1)static final用來修飾成員變量和成員方法,可以了解為“全局變量”
(2)對于變量,表示一旦給值就不可修改,并且通過類名可以通路。
(3)對于方法,表示不可覆寫,并且可以通過類名直接通路。
注意:
對于被static和final修飾過的執行個體常量,執行個體本身不能再改變了,但對于一些容器類型(比如,ArrayList、HashMap)的執行個體變量,不可以改變容器變量本身,但可以修改容器中存放的對象。
代碼示範:
package com.Test;
import java.util.ArrayList;
public class Test {
private static final String strStaticFinalVar = "磊哥的java曆險記";
private static String strStaticVar = null;
private final String strFinalVar = null;
private static final int intStaticFinalVar = 0;
private static final Integer integerStaticFinalVar = new Integer(8);
private static final ArrayList<String> alStaticFinalVar = new ArrayList<String>();
private void test() {
System.out.println("-------------值處理前----------");
System.out.println("strStaticFinalVar=" + strStaticFinalVar + "");
System.out.println("strStaticVar=" + strStaticVar + "");
System.out.println("strFinalVar=" + strFinalVar + "");
System.out.println("intStaticFinalVar=" + intStaticFinalVar + "");
System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "");
System.out.println("alStaticFinalVar=" + alStaticFinalVar + "");
//錯誤,final表示終态,不可以改變變量本身.
//strStaticFinalVar="哈哈哈哈";
//正确,static表示類變量,值可以改變
strStaticVar = "_51部落格";
//錯誤, final表示終态,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
//strFinalVar="呵呵呵呵";
//錯誤, final表示終态,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
//intStaticFinalVar=2;
//integerStaticFinalVar=new
//錯誤, final表示終态,在定義的時候就要初值(哪怕給個null),一旦給定後就不可再更改。
//Integer(8);
//正确,容器變量本身沒有變化,但存放内容發生了變化。這個規則是非常常用的,有很多用途。
alStaticFinalVar.add("aaa");
//正确,容器變量本身沒有變化,但存放内容發生了變化。這個規則是非常常用的,有很多用途。
alStaticFinalVar.add("bbb");
System.out.println("-------------值處理後----------");
System.out.println("strStaticFinalVar=" + strStaticFinalVar + "");
System.out.println("strStaticVar=" + strStaticVar + "");
System.out.println("strFinalVar=" + strFinalVar + "");
System.out.println("intStaticFinalVar=" + intStaticFinalVar + "");
System.out.println("integerStaticFinalVar=" + integerStaticFinalVar + "");
System.out.println("alStaticFinalVar=" + alStaticFinalVar + "");
}
public static void main(String args[])
{
new Test().test();
}
}
結語:
隻有向前不斷行走,才能有始有終。當你想要放棄的時候,就想想一開始你是怎樣的拼盡全力;當你想要逃避的時候,就回頭看看當初那個堅定執着的你。
我從不知道順其自然有多自然,但我知道現實有多現實。
感謝兄弟們的持續關注!