zoukankan      html  css  js  c++  java
  • 对JavaBean创建的一点改进

    在看了《Effective Java》Item2中对JavaBean的描述后,再结合Item1和Builder模式,遂想有没有其他方式避免JavaBean创建的线程安全问题呢?

    以如下JavaBean类为例,

    public class JavaBean {
    
        private int count;
        private String level;
        private List<String> messages;
    
        public int getCount() {
            return count;
        }
    
        public void setCount(int count) {
            this.count = count;
        }
    
        public String getLevel() {
            return level;
        }
    
        public void setLevel(String level) {
            this.level = level;
        }
    
        public List<String> getMessages() {
            return messages;
        }
    
        public void setMessages(List<String> messages) {
            this.messages = messages;
        }
    }

    分步创建对象如下,因为几个set方法的调用导致对象的状态可能不一致,存在线程安全问题。比如javaBean对象在执行一系列set方法过程中,其他线程调用get方法,这时得到的属性值可能就不对了。

    JavaBean javaBean = new JavaBean();
    javaBean.setCount(1);
    javaBean.setLevel("first");
    javaBean.setMessages(new ArrayList<String>());

    为了避免创建过程中被访问,可以用匿名对象+链式调用的方式,如下代码,

    public class JavaBean {
    
        private int count;
        private String level;
        private List<String> messages;
    
        public int getCount() {
            return count;
        }
    
        public JavaBean setCount(int count) {
            this.count = count;
            return this;
        }
    
        public String getLevel() {
            return level;
        }
    
        public JavaBean setLevel(String level) {
            this.level = level;
            return this;
        }
    
        public List<String> getMessages() {
            return messages;
        }
    
        public JavaBean setMessages(List<String> messages) {
            this.messages = messages;
            return this;
        }
    }
    JavaBean javaBean1 = new JavaBean().setCount(1).setLevel("second").setMessages(new ArrayList<String>());
    System.out.println(javaBean1.getLevel());

    以上写法只有对象完全初始化好后,才将引用赋给javaBean1,避免创建过程中被其他线程访问。

    但这个时候,以上分步创建对象的方式仍然可以用。怎么能强制使用链式调用呢?想来想去觉得还得对链式调用进行封装。

    增加如下代码,

    private JavaBean(){ }
    
    public static JavaBean newInstance(){
        return new JavaBean();
    }
    
    public static JavaBean newInstance(int count, String level){
        return new JavaBean().setCount(count).setLevel(level);
    }

    这样一来,实际上跟直接使用参数化的构造函数一样,如下

    public JavaBean(){ }
    
    public JavaBean(int count, String level){
        this.count = count;
        this.level = level;
    }

    总结:

    1. 在写JavaBean时,set方法尽量返回JavaBean类型;

    2. 在创建对象时,尽量使用链式调用。

  • 相关阅读:
    sencha touch 扩展篇之将sencha touch打包成安装程序(上)- 使用sencha cmd打包安装程序
    sencha touch 扩展篇之使用sass自定义主题样式 (下)通过css修改官方组件样式以及自定义图标
    一个不错的android组件的网站
    sencha touch 扩展篇之使用sass自定义主题样式 (上)使用官方的api修改主题样式
    sencha touch 入门系列 (九) sencha touch 布局layout
    面试题总结
    国外接活网站Elance, Freelancer和ScriptLance的介绍和对比
    sencha touch 入门系列 扩展篇之sencha touch 项目打包压缩
    Android Design Support Library——Navigation View
    设计模式——命令模式
  • 原文地址:https://www.cnblogs.com/hello-yz/p/9844676.html
Copyright © 2011-2022 走看看