• 如何创建不可变的Java类或对象


       在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,本文主要讲述如何创建不可变的Java类或对象,更多Java专业知识,广州疯狂java培训官网与你分享;

      immutable Objects就是那些一旦被创建,它们的状态就不能被改变的Objects,每次对他们的改变都是产生了新的immutable的对象,而mutable Objects就是那些创建后,状态可以被改变的Objects.

      举个例子:String和StringBuilder,String是immutable的,每次对于String对象的修改都将产生一个新的String对象,而原来的对象保持不变,而StringBuilder是mutable,因为每次对于它的对象的修改都作用于该对象本身,并没有产生新的对象。

      但有的时候String的immutable特性也会引起安全问题,这就是密码应该存放在字符数组中而不是String中的原因!

      immutable objects 比传统的mutable对象在多线程应用中更具有优势,它不仅能够保证对象的状态不被改变,而且还可以不使用锁机制就能被其他线程共享。

      实际上JDK本身就自带了一些immutable类,比如String,Integer以及其他包装类。为什么说String是immutable的呢?比如:java.lang.String 的trim,uppercase,substring等方法,它们返回的都是新的String对象,而并不是直接修改原来的对象。

      如何在Java中写出Immutable的类?

      要写出这样的类,需要遵循以下几个原则:

      1)immutable对象的状态在创建之后就不能发生改变,任何对它的改变都应该产生一个新的对象。

      2)Immutable类的所有的属性都应该是final的。

      3)对象必须被正确的创建,比如:对象引用在对象创建过程中不能泄露(leak)。

      4)对象应该是fianl的,以此来限制子类继承父类,以避免子类改变了父类的immutable特性。

      5)如果类中包含mutable类对象,那么返回给客户端的时候,返回该对象的一个拷贝,而不是该对象本身(该条可以归为第一条中的一个特例)

      当然不完全遵守上面的原则也能够创建immutable的类,比如String的hashcode就不是final的,但它能保证每次调用它的值都是一致的,无论你多少次计算这个值,它都是一致的,因为这些值的是通过计算final的属性得来的!

      另外,如果你的Java类中存在很多可选的和强制性的字段,你也可以使用建造者模式来创建一个immutable的类。

      下面是一个例子:

      public final class Contacts {

      private final String name;

      private final String mobile;

      public Contacts(String name, String mobile) {

      this.name = name;

      this.mobile = mobile;

      }

      public String getName(){

      return name;

      }

      public String getMobile(){

      return mobile;

      }

      }

      我们为类添加了final修饰,从而避免因为继承和多态引起的immutable风险。

      上面是最简单的一种实现immutable类的方式,可以看到它的所有属性都是final的。

      有时候你要实现的immutable类中可能包含mutable的类,比如java.util.Date,尽管你将其设置成了final的,但是它的值还是可以被修改的,为了避免这个问题,我们建议返回给用户该对象的一个拷贝,这也是Java的最佳实践之一。下面是一个创建包含mutable类对象的immutable类的例子:

      public final class ImmutableReminder{

      private final Date remindingDate;

      public ImmutableReminder (Date remindingDate) {

      if(remindingDate.getTime() < System.currentTimeMillis()){

      throw new IllegalArgumentException("Can not set reminder” +

      “ for past time: " + remindingDate);

      }

      this.remindingDate = new Date(remindingDate.getTime());

      }

      public Date getRemindingDate() {

      return (Date) remindingDate.clone();

      }

      }

      上面的getRemindingDate()方法可以看到,返回给用户的是类中的remindingDate属性的一个拷贝,这样的话如果别人通过getRemindingDate()方法获得了一个Date对象,然后修改了这个Date对象的值,那么这个值的修改将不会导致ImmutableReminder类对象中remindingDate值的修改。

      使用Immutable类的好处:

      1)Immutable对象是线程安全的,可以不用被synchronize就在并发环境中共享

      2)Immutable对象简化了程序开发,因为它无需使用额外的锁机制就可以在线程间共享

      3)Immutable对象提高了程序的性能,因为它减少了synchroinzed的使用

      4)Immutable对象是可以被重复使用的,你可以将它们缓存起来重复使用,就像字符串字面量和整型数字一样。你可以使用静态工厂方法来提供类似于valueOf()这样的方法,它可以从缓存中返回一个已经存在的Immutable对象,而不是重新创建一个。

      immutable也有一个缺点就是会制造大量垃圾,由于他们不能被重用而且对于它们的使用就是”用“然后”扔“,字符串就是一个典型的例子,它会创造很多的垃圾,给垃圾收集带来很大的麻烦。

      当然这只是个极端的例子,合理的使用immutable对象会创造很大的价值。

      疯狂java是java培训行业的一匹黑马,专注于高级软件编程,疯狂java体系包括《疯狂Java讲义》、《疯狂Android讲义》、《轻量级Java EE企业应用实战》等著作。其中疯狂Java体系图书都是已经得到广泛的市场认同,并多次重印的畅销图书,并被多所高等院校选作教材。疯狂Java培训紧跟最前沿的技术潮流,采用的都是企业最真实的项目开发,培养学生的实践动手能力。技术在不断更新换代,在疯狂软件学院能学到最前沿的Java技术,疯狂Java培训主要培养的是Java专业人才,android专业人才。学员毕业之后的代码量至少达到项目经理的水平。疯狂软件学院有完善的就业服务机制,学员毕业时,可以享受免费终身推荐就业服务。根据学员的特点和企业的要求,为学员推荐最合适的岗位。

  • 相关阅读:
    MySQL "show users"
    MySQL
    A MySQL 'create table' syntax example
    MySQL backup
    MySQL show status
    Tomcat, pathinfo, and servlets
    Servlet forward example
    Servlet redirect example
    Java servlet example
    How to forward from one JSP to another JSP
  • 原文地址:https://www.cnblogs.com/gojava/p/3355634.html
Copyright © 2020-2023  润新知