【问题标题】:Read only classes/methods只读类/方法
【发布时间】:2013-01-10 04:36:22
【问题描述】:

在准备面试时,有人提到知道如何将 java 中的类/方法设为只读。我一直在做一些搜索,但没有找到任何具体的东西。

也许这个问题比我想象的更容易回答,但是在 java 中使类或方法只读的方法是什么?

【问题讨论】:

  • 他们是在谈论final吗?
  • 你要找的词是“不可变的”

标签: java oop


【解决方案1】:

一种解决方案是创建属于只读类的immutable 对象。您可以定义一个类,使类中的任何方法都不会导致对象的内部状态发生变化。在这样的类中,别名没有影响,因为您只能读取内部状态,因此如果许多段代码正在读取同一个对象,则没有问题。

要创建不可变对象,请查看以下链接:

  1. how-to-create-immutable-objects-in-java

【讨论】:

    【解决方案2】:

    以下代码将确保您的课程始终为只读,但如果您发现任何漏洞,请在此处发布。

    import java.io.Serializable;
    
    final public class ImmutableClass implements Cloneable,Serializable {
        private static final long serialVersionUID = 6488148163144293060L;
        private static volatile ImmutableClass instance;
    
        private ImmutableClass() {
            // no-op
            System.out.println("instance created : " + this.hashCode());
        }
    
        /**
         * Lazy Instantiation
         * 
         * @return
         */
        public static ImmutableClass getInstance() {
            if (instance == null) {
                synchronized (ImmutableClass.class) {
                    System.out.println("aquired lock");
                    if (instance == null) {
                        instance = new ImmutableClass() {
                        };
                    }
                    System.out.println("released lock");
                }
            }
            return instance;
        }
    
        public Object readResolve() {
            System.out.println("readResolve()");
            return getInstance();
        }
    
        @Override
        public Object clone() throws CloneNotSupportedException {
            throw new CloneNotSupportedException();
        }
    
    }
    

    【讨论】:

      【解决方案3】:

      Read-only 类意味着,我们正在谈论“IMMUTABLE”的概念。

      以下示例描述相同:

      public class ImmutableString { 
          static String upcase(String s) { 
              return s.toUpperCase(); // here local variable s vanishes 
                      // it return the value to a new String object 
          } 
      
          public static void main(String[] args) { 
              String s = new String("abc");  
              System.out.println(s); //abc 
      
              String s1 = upcase(s);  
      
              System.out.println(s1); //ABC 
              System.out.println(s); //abc 
          } 
      }  
      

      【讨论】:

        【解决方案4】:

        假设您想要一个对象的只读版本,

        案例 1:如果您的类包含不是指向任何其他对象的指针的字段,例如:

        public class Person{
        private String name;
        //Getters n Setters
        }
        

        在这种情况下,您可以返回该类的副本,编写一个接受 Person 的构造函数,任何想要获取 Person 对象的人都将拥有该对象的副本,因此任何 Setter 操作都不会影响原始对象(字符串是不可变的)

        案例 2:如果您的对象包含指向另一个对象或列表或映射的指针

        在这种情况下,使类实现一个只有只读方法(Getters)的接口,并且无论您在何处返回对象,都将其更改为返回此接口,因此客户端将只能访问只读方法

        例如:

        class Person implements ReadOnly{
        String name;
        .. assume pointers also in here
        // Getter n Setters 
        
         public PersonReadOnly(){
          return this;
        }
        }
        
        interface PersonReadOnly {
        public String getName();
        }
        

        【讨论】:

        • 第二种状态有一些问题。可以将返回的对象(实现 ReadOnly 接口)强制转换为 Person。之后,所有的 setter 方法都可用。
        • 我认为改进第二种状态:我们可以从 Preson 扩展另一个类,并将其设置方法作为一个空方法,当调用其中一个设置方法时不执行任何操作或抛出异常。
        【解决方案5】:

        简单的规则:不要有任何公共字段和没有公共的setter方法。

        例如,看下面的类:

        final class AReadOnlyClass
        {
            private int anInt;
        
            public int GetAnInt()
            {
                return anInt;
            }
        }
        

        【讨论】:

        • final 并不意味着只读(原始类型除外)。 final 变量引用的对象的值仍然可以更改。
        • 是的,同意。但引用将始终指向同一个对象。在这种情况下,它是最终的。
        • final 与不变性无关。您的课程就是一个很好的例子,只需去掉答案中的 final 内容即可。
        • 正如@BrianRoach 评论的那样,您的示例中的 final 告诉这个类不能扩展,这并不意味着它不能被实例化。
        • @Nambari,BrianRoach:通过使其成为最终的,我们不必担心通过覆盖某些方法来改变方法行为。这就是为什么我将其标记为final
        猜你喜欢
        • 1970-01-01
        • 2015-01-17
        • 1970-01-01
        • 1970-01-01
        • 2016-08-17
        • 2020-02-22
        • 2015-05-19
        • 2018-10-17
        相关资源
        最近更新 更多