題目描述

靜態初始化區塊會在類別被載入之後執行,您可以在這個區塊內初始化類別的靜態變數或常數。這個題目會測試您對靜態初始化區塊的認知。



您現在有一個Solution類別和main物件方法。接著必須要在類別初始化的時候從標準輸入串流中讀取寬度B(breadth)和高度H(height)。若讀取到的B或是H小於等於0,要輸出「java.lang.Exception: Breadth and height must be positive」。

原題網址

輸入格式

輸入為兩行整數。第一行是B的值,範圍在-100到100(包含-100和100)之間。第二行是H的值,範圍在-100到100(包含-100和100)之間。

輸出格式

如果B和H都大於0,那麼輸出計算面積(BxH)後的結果。否則輸出「java.lang.Exception: Breadth and height must be positive」。

範例輸入1

1
3

範例輸出1

3

範例輸入2

-1
2

範例輸出2

java.lang.Exception: Breadth and height must be positive

解題概念

這題由於HackerRank已經限制了可寫的程式範圍,因此我們只能朝靜態初始化區塊下手。究竟什麼是「靜態初始化區塊」?該寫在哪裡呢?

每個類別,都有分靜態成員(static member)和物件成員(或稱實體成員, instance member)。類別的靜態成員在載入類別之後就會存在,而物件成員則是在類別被new運算子實體化成物件的時候才會存在。無論是類別還是物件,當它們在初始化的時候,都有個初始區塊。類別的初始化區塊就是靜態初始化區塊,將區塊直接以static來修飾,當類別載入的時候就會立刻執行,程式結構如下:

class A{
    static {
        // 這就是類別(靜態)初始化區塊
    }
}

而物件的初始化區塊,則沒有任何的修飾子,程式結構如下:

class A{
    {
        // 這就是物件初始化區塊
    }
}

若要將類別實體化成一個物件,那麼首先會先從其繼承關係之最頂層的父類別開始,執行該類別的初始化區塊,再來執行物件的初始化區塊,最後才是物件的建構子(Constructor),再來往下一層繼續執行該類別的初始化區塊、物件的初始化區塊和物件的建構子,當子類別被的建構子被執行完成後,物件才算是實體化成功。

這題不用考慮到物件的特性,只要知道靜態初始化區塊怎麼使用即可。

參考答案

package org.magiclen.hackerrank;

import java.util.Scanner;

public class Solution {

    private final static int B, H;
    private static boolean flag;

    static {
        final Scanner sc = new Scanner(System.in);
        B = sc.nextInt();
        H = sc.nextInt();
        if (B > 0 && H > 0) {
            flag = true;
        } else {
            System.out.println("java.lang.Exception: Breadth and height must be positive");
        }
    }

    public static void main(final String[] args) {

        if (flag) {
            int area = B * H;
            System.out.print(area);
        }
    }
}