Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「Effective Java」Notes #6

Open
Sitrone opened this issue Oct 26, 2016 · 1 comment
Open

「Effective Java」Notes #6

Sitrone opened this issue Oct 26, 2016 · 1 comment

Comments

@Sitrone
Copy link
Owner

Sitrone commented Oct 26, 2016

Item 3 单例模式

饿汉式 static final method

public class Singleton{
    //类加载时就初始化
    private static final Singleton instance = new Singleton();

    private Singleton(){}

    public static Singleton getInstance(){
        return instance;
    }
}

注意,这种方法实现序列化接口的时候会有问题

  • 在序列化后,再经过反序列化会得到一个不同的对象,需要在单例类中加入readResolve()方法,才能防止反序列化生成的对象与原有对象不是同一对象的问题 , 具体实现如下:
public class SingletonSerizlizable implements Serializable{
 private static final SingletonSerizlizable INSTANCE=new SingletonSerizlizable();
 private SingletonSerizlizable(){};
 public static SingletonSerizlizable getInstance()
 {
   return INSTANCE;
 }

private Object readResolve()
{
 return INSTANCE;//依旧返回最初创建的对象,不再创建新对象
}
 public static void main(String[] args) {
   // TODO Auto-generated method stub

 }

}

静态内部类 static nested class

public class Singleton {  
    private static class SingletonHolder {  
        private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
        return SingletonHolder.INSTANCE; 
    }  
}

枚举

public enum Elvis {
    INSTANCE;

    public void levaveTheBuilding(){
        System.out.println("leave ...");
    }

    public static void main(String[] args){
        Elvis singleton = Elvis.INSTANCE;
        singleton.levaveTheBuilding();
    }
}

Effective Java作者最推荐的方式,多线程安全,简单,序列化和反序列化没有问题。

Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant’s name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant’s enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream. The process by which enum constants are serialized cannot be customized: any class-specific writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods defined by enum types are ignored during serialization and deserialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored–all enum types have a fixedserialVersionUID of 0L. Documenting serializable fields and data for enum types is unnecessary, since there is no variation in the type of data sent.


Ref

  1. Effective Java 第三条单例模式的序列化的思考
  2. 如何正确地写出单例模式
@Sitrone
Copy link
Owner Author

Sitrone commented Nov 11, 2016

Item 21用函数对象表示策略

package test;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Random;

public class Host
{
    /*
     * [Effective Java #21] 用函数对象来表示策略
     */
    private static class StrLenCmp implements Comparator<String>, Serializable
    {
        // default serialVersionUID
        private static final long serialVersionUID = 1L;

        @Override
        public int compare(String o1, String o2)
        {
            return o1.length() - o2.length();
        }
    }

    public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StrLenCmp();

    public static void main(String[] args)
    {
        int len = 10;
        String[] stringArray = new String[len];
        while(len-- != 0)
        {
            stringArray[9 - len] = getRandomStr(9 - len);
        }
        Collections.shuffle(Arrays.asList(stringArray));
        System.out.println(Arrays.toString(stringArray));

        // 考虑到重复执行,将策略存储到一个私有的静态final域中
        Arrays.sort(stringArray, Host.STRING_LENGTH_COMPARATOR);
        System.out.println(Arrays.toString(stringArray));

        // 没有实现策略模式的, 每次调用都会生成新的一个实例
        Arrays.sort(stringArray, new Comparator<String>()
        {

            @Override
            public int compare(String o1, String o2)
            {
                return o1.length() - o2.length();
            }
        });
    }

    public static String getRandomStr(int len)
    {
        String target = "abcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder result = new StringBuilder("1");
        Random rd = new Random();
        while(len-- != 0)
        {
            result.append(target.charAt(rd.nextInt(target.length())));
        }

        return result.toString();
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant