題目描述

您將會得到一個Solution類別,在Solution類別有個內部類別Inner,Inner類別中也還有個內部類別Private。Solution類別的main方法會從標準輸入中讀取一個整數num。Private類別的powerof2方法會檢查傳入的數字是否為2的冪次。您必須要在Solution類別的main方法中呼叫Private類別的powerof2方法來判斷讀取到的整數是否為2的冪次。



原題網址

https://www.hackerrank.com/challenges/can-you-access

輸入格式

輸入一個整數num,範圍在1到230之間(包含1和230)。

輸出格式

請見範例。

範例輸入

8

範例輸出

8 is power of 2
An instance of class: Solution.Inner.Private has been created

解題概念

若要實體化出內部類別,需先區分內部類別屬於類別的內部類別還是物件的內部類別(看類別的宣告有無使用static關鍵字)。如果沒有使用static關鍵字,那就和一般的物件成員一樣,必須先將外部類別實體化出來之後,才可以使用到屬於物件成員的內部類別。舉例來說,若A類別中有物件類別B,類別B中又有物件類別C,若要在A的類別方法中實體化出類別C,則必須先實體化出A類別的物件,再用A類別的物件實體化出B類別的物件,再用B類別的物件實體化出C類別的物件。程式如下:

A.B.C c = new A().new B().new C();

擁有內部物件類別的物件可以使用「.」來呼叫該物件的new運算子。這種用法比較不常見,但Java程式語言是可以用這樣的方式實體化出內部類別的內部類別物件的哦!

參考答案

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.security.Permission;

public class Solution {
    
    public static void main(final String[] args) throws Exception {
        Do_Not_Terminate.forbidExit();
        
        try {
            final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            final int num = Integer.parseInt(br.readLine().trim());
            final Object o;
            o = new Inner().new Private();
            System.out.printf("%d is %s%n", num, ((Inner.Private) o).powerof2(num));
            System.out.println("An instance of class: " + o.getClass().getCanonicalName() + " has been created");
        } catch (Do_Not_Terminate.ExitTrappedException e) {
            System.out.println("Unsuccessful Termination!!");
        }
    }
    
    static class Inner {
        
        private class Private {
            
            private String powerof2(final int num) {
                return ((num & num - 1) == 0) ? "power of 2" : "not a power of 2";
            }
        }
    }
}

class Do_Not_Terminate {
    
    public static class ExitTrappedException extends SecurityException {
        
        private static final long serialVersionUID = 1L;
    }
    
    public static void forbidExit() {
        final SecurityManager securityManager = new SecurityManager() {
            @Override
            public void checkPermission(Permission permission) {
                if (permission.getName().contains("exitVM")) {
                    throw new ExitTrappedException();
                }
            }
        };
        System.setSecurityManager(securityManager);
    }
}