Java 靜態(tài)塊 Android 中的使用實例

靜態(tài)塊也被稱為靜態(tài)初始化塊。靜態(tài)初始化塊是以 static 關(guān)鍵字開頭并用大括號括起來的正常的代碼塊 。下面是一個例子:

static {
    // whatever code is needed for initialization goes here
}

靜態(tài)塊在 Java 中的使用實例:

public class StaticExample{
    static {
        System.out.println("This is first static block");
    }

    public StaticExample(){
        System.out.println("This is constructor");
    }

    public static String staticString = "Static Variable";

    static {
        System.out.println("This is second static block and "
                                                + staticString);
    }

    public static void main(String[] args){
        StaticExample statEx = new StaticExample();
        StaticExample.staticMethod2();
    }

    static {
        staticMethod();
        System.out.println("This is third static block");
    }

    public static void staticMethod() {
        System.out.println("This is static method");
    }

    public static void staticMethod2() {
        System.out.println("This is static method2");
    }
}

以上代碼的輸出結(jié)果:

This is first static block
This is second static block and Static Variable
This is static method
This is third static block
This is constructor
This is static method2

如果代碼塊前面不加 “static” 關(guān)鍵字,那么這個塊被稱為“構(gòu)造塊”,并且在類每次被實例化時都將被執(zhí)行。構(gòu)造函數(shù)塊將被復(fù)制到類的每個構(gòu)造函數(shù)中。例如,我們有四個參數(shù)化的構(gòu)造函數(shù),那么四個構(gòu)造塊的副本將被放置在構(gòu)造函數(shù)中,每個構(gòu)造函數(shù)一個。讓我們執(zhí)行下面的例子,看看輸出:

public class ConstructorBlockExample{

    {
        System.out.println("This is first constructor block");
    }

    public ConstructorBlockExample(){
        System.out.println("This is no parameter constructor");
    }

    public ConstructorBlockExample(String param1){
        System.out.println("This is single parameter constructor");
    }

    public ConstructorBlockExample(String param1, String param2){
        System.out.println("This is two parameters constructor");
    }

    {
        System.out.println("This is second constructor block");
    }

    public static void main(String[] args){
        ConstructorBlockExample constrBlockEx = 
                     new ConstructorBlockExample();
        ConstructorBlockExample constrBlockEx1 = 
                     new ConstructorBlockExample("param1");
        ConstructorBlockExample constrBlockEx2 = 
                     new ConstructorBlockExample("param1", "param2");
    }
}

上面的代碼的輸出結(jié)果:

This is first constructor block
This is second constructor block
This is no parameter constructor
This is first constructor block
This is second constructor block
This is single parameter constructor
This is first constructor block
This is second constructor block
This is two parameters constructor

我們應(yīng)該用私有靜態(tài)方法去初始化公有的靜態(tài)變量:

class Whatever {
    private varType myVar = initializeInstanceVariable();
        
    protected final varType initializeInstanceVariable() {

        // initialization code goes here
    }
}

私有靜態(tài)方法的優(yōu)點是,如果需要重新初始化公有的靜態(tài)變量,可以更加靈活地重用私有靜態(tài)方法。因此,與相應(yīng)的靜態(tài)初始化塊相比,我們可以通過私有靜態(tài)方法獲得更大的靈活性。我們不是說公有的靜態(tài)方法不能做到這一點。 只是,我們正在談?wù)撘环N初始化類變量的方法,幾乎沒有任何理由使這種初始化的方法“公開”。

那么靜態(tài)塊的優(yōu)點是什么?
  • 如果我們正在加載驅(qū)動程序和其他項目到命名空間。例如,Class類有一個靜態(tài)塊,它注冊了本機。
  • 如果我們需要執(zhí)行計算來初始化您的靜態(tài)變量,那么您可以聲明一個靜態(tài)塊,該類在第一次加載時才會被執(zhí)行一次。
  • 與安全相關(guān)的問題或與日志記錄相關(guān)
當(dāng)然靜態(tài)塊也有局限性
  • JVM 的一個限制是靜態(tài)初始化塊不應(yīng)該超過 64K
  • 不能拋出檢查異常
  • 不能使用 this 關(guān)鍵字,因為還沒有其實例
  • 不應(yīng)該嘗試訪問 super,因為對靜態(tài)塊來說沒有這樣 super
  • 不應(yīng)該從這個塊返回任何東西
  • 靜態(tài)塊可能會使測試成為一場噩夢
最后如何處理靜態(tài)塊中的異常?

在方法中,可以通過異常處理或處理異常來處理異常。但是在靜態(tài)塊代碼中,你不能以這種方式處理異常。

通常一個干凈利落的方式來處理它是使用 try-catch 塊,但在靜態(tài)塊代碼中,因為我們沒有這個選項,因此讓我們看看可用的三個選項:

首先在記錄異常之后拋出一個 RuntimeException,它將結(jié)束當(dāng)前線程(除非被代碼初次實例化或者在類上第一次調(diào)用靜態(tài)方法)。

其次是調(diào)用 System.exit(1),但是這在像 servlet 這樣的托管環(huán)境中是不可取的。此選項僅適用于 Java 應(yīng)用程序,并且只有在靜態(tài)初始化塊執(zhí)行一些關(guān)鍵操作(沒有這些關(guān)鍵操作,程序無法成功運行)的情況下,才能加載數(shù)據(jù)庫驅(qū)動程序。

最后一個選項是設(shè)置一個標(biāo)志指示失敗。稍后,構(gòu)造函數(shù)可以檢查標(biāo)志并在需要的情況下拋出異?;蛑卦嚒?/p>

最后,如果操作對程序的功能不重要,那么可能只需要一個簡單的日志。

靜態(tài)塊 在 Android 中的使用實例

代碼如下:

package com.toby.test_application;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends Activity {

    private static final String TAG = "Test_MainActivity";

    private static IntentFilter s_intentFilter;
    private static List<String> s_stringList;

    static {
        s_intentFilter = new IntentFilter();
        s_intentFilter.addAction(Intent.ACTION_TIME_TICK);
        s_intentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
        s_intentFilter.addAction(Intent.ACTION_TIME_CHANGED);

        s_stringList = new ArrayList<>();
        s_stringList.add("one");
        s_stringList.add("two");
        s_stringList.add("three");
        s_stringList.add("four");
    }

    private final BroadcastReceiver m_testReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();

            if (action.equals(Intent.ACTION_TIME_CHANGED) ||
                    action.equals(Intent.ACTION_TIMEZONE_CHANGED))
            {
                // TODO: 17-11-14 something
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        registerReceiver(m_testReceiver, s_intentFilter);

        Log.d(TAG, "s_intentFilter hasAction ACTION_TIME_TICK: "
                + s_intentFilter.hasAction(Intent.ACTION_TIME_TICK));
        Log.d(TAG, "s_intentFilter hasAction ACTION_TIMEZONE_CHANGED: "
                + s_intentFilter.hasAction(Intent.ACTION_TIMEZONE_CHANGED));
        Log.d(TAG, "s_intentFilter hasAction ACTION_TIME_CHANGED: "
                + s_intentFilter.hasAction(Intent.ACTION_TIME_CHANGED));

        Log.d(TAG, s_stringList.toString());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(m_testReceiver);
    }
}

上面的代碼的輸出結(jié)果:

輸出結(jié)果

本文參考鏈接:
http://java2novice.com/java-fundamentals/static/block/
http://jusfortechies.com/java/core-java/static-blocks.php
https://stackoverflow.com/questions/5481386/date-and-time-change-listener-in-android

最后編輯于
?著作權(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)容

  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,812評論 0 11
  • (一)Java部分 1、列舉出JAVA中6個比較常用的包【天威誠信面試題】 【參考答案】 java.lang;ja...
    獨云閱讀 7,256評論 0 62
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,670評論 18 399
  • 這是一則關(guān)于西藏的臆想。 藏族。青稞。雪山。倉央嘉措。朝圣。 西藏,是很多人的夢想。 如果你相信星座的話,那我告訴...
    囈籽閱讀 263評論 0 1
  • 你所見到的,只不過是自己的想象;你以為是自己的,只不過是種偶然。——梁文道 《我執(zhí)》 我知道我們有種傾向,總是想神...
    重復(fù)和回憶閱讀 315評論 0 0

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