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. 在创建对象时,尽量使用链式调用。

  • 相关阅读:
    Spring Cloud Data Flow整合UAA之使用LDAP进行账号管理
    2020,分手快乐;2021,且行且歌
    Spring Cloud Data Flow整合UAA使用外置数据库和API接口
    Spring Cloud Data Flow整合Cloudfoundry UAA服务做权限控制
    Spring自定义转换类,让@Value更方便
    2020年11月CKA新题考试心得体会
    使用Go module和GoLand初始化一个Go项目
    Spring Cloud Gateway简单入门,强大的微服务网关
    vue百度地图实现自定义覆盖物
    vue 中安装使用jquery
  • 原文地址:https://www.cnblogs.com/hello-yz/p/9844676.html
Copyright © 2011-2022 走看看