1. 程式人生 > >單例模式 靜態內部類 解決反射得到多個物件

單例模式 靜態內部類 解決反射得到多個物件

首先這裡就不說單例模式的餓漢式,懶漢式了,如果需要請百度

餓漢式,懶漢式好一點的是靜態內部類單例

這裡貼出程式碼

package com.test;

public class SimpleTest {
	
	private static class SimpleNB {
		
		private static final SimpleTest INSTANCE = new SimpleTest();
	}

	private SimpleTest() {

	}

	public static SimpleTest getIns() {
		return SimpleNB.INSTANCE;
	}
}
但是這種方式還是會存在我通過反射去得到他的構造方法,然後把構造方法改為公共的,然後newInstance()建立物件

這裡貼出程式碼

package com.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

/**
 * @date 2017-10-20
 * @author xgf
 *
 */
public class Test {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

		
		Constructor<SimpleTest> declaredConstructor = SimpleTest.class.getDeclaredConstructor();
		declaredConstructor.setAccessible(true);
		SimpleTest newInstance1 =declaredConstructor.newInstance();
		SimpleTest newInstance2 =declaredConstructor.newInstance();
		System.out.println(newInstance1.equals(newInstance2));
	}
}
這裡得到的結果為false

貼出圖片




然後根據這個問題,想出解決辦法  用列舉,原因是jvm 因為列舉 ,而構造器 可見性 是不可改變的

這裡貼出程式碼

package com.test;




public enum Singleton6
{
    INSTANCE;
    
    private SimpleTest instance;
    
    Singleton6()
    {
        instance = SimpleTest.getIns();
    }
    
    public SimpleTest getInstance()
    {
        return instance;
    }
    
    
}
然後是測試程式碼
package com.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;

/**
 * @date 2017-10-20
 * @author xgf
 *
 */
public class Test {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Constructor<Singleton6> declaredConstructor = Singleton6.class.getDeclaredConstructor();
		declaredConstructor.setAccessible(true);
		Singleton6 newInstance1 =declaredConstructor.newInstance();
		Singleton6 newInstance2 =declaredConstructor.newInstance();
		System.out.println(newInstance1.equals(newInstance2));
//		Singleton6 instance1 = Singleton6.INSTANCE;
//		Singleton6 instance2 = Singleton6.INSTANCE;
//		System.out.println(instance1.equals(instance2));
		
//		Constructor<SimpleTest> declaredConstructor = SimpleTest.class.getDeclaredConstructor();
//		declaredConstructor.setAccessible(true);
//		SimpleTest newInstance1 =declaredConstructor.newInstance();
//		SimpleTest newInstance2 =declaredConstructor.newInstance();
//		System.out.println(newInstance1.equals(newInstance2));
	}
}

然後貼出控制檯輸出結果


到這裡,基本應該懂了吧,能看到這裡的人,我只希望大家能也多分享一些(不論是技術還是任何其他事),感恩前人。有什麼問題,請評論或者給我發私信,謝謝大家