Java 使用StringBuffer如何实现100%的不变性。。我只想用stringbuffer来做。没有其他数据类型

Java 使用StringBuffer如何实现100%的不变性。。我只想用stringbuffer来做。没有其他数据类型,java,Java,考虑以下代码 final class immudemo { private static final StringBuffer bf = new StringBuffer("Yaxita"); public StringBuffer getter() { return bf; } } public class HelloWorld{ public static void main (String args[])

考虑以下代码

final class immudemo
{
      private static final StringBuffer bf = new StringBuffer("Yaxita");
      public StringBuffer getter()
      {
           return bf;
      }
}

public class HelloWorld{

     public static void main (String args[])
     {
         immudemo obj1 = new immudemo();
         StringBuffer bf2 = obj1.getter();
         bf2.append("Shah");
         System.out.println(obj1);
     }
}
在上面的代码中,即使StringBuffer声明为final,我也可以更改它。谁能帮我实现100%的不变性


附言:我只想用StringBuffer实现这一点。如果您提供了任何内容,请检查它是否仅与StringBuffer相关。

使用您定义的final,您不能将另一个对象设置为“bf”。 如果对象本身是可变的,则其状态仍然可以更改。 StringBuffer就是这样。因为您通过“getter”将其发布到外部,所以您的类“immudemo”也是可变的

如果使用字符串作为“getter”的返回类型,那么外部将有一个不可变对象,而内部将有一个可变对象。 (您的类“immudemo”不需要是其实例的不变性的最终类。)

因此,如果通过方法“getter”返回类型字符串而不是StringBuffer,则类“immudemo”将是不可变的


附加:按照此策略自己定义不可变对象:

使用您定义的final,您不能将另一个对象设置为“bf”。 如果对象本身是可变的,则其状态仍然可以更改。 StringBuffer就是这样。因为您通过“getter”将其发布到外部,所以您的类“immudemo”也是可变的

如果使用字符串作为“getter”的返回类型,那么外部将有一个不可变对象,而内部将有一个可变对象。 (您的类“immudemo”不需要是其实例的不变性的最终类。)

因此,如果通过方法“getter”返回类型字符串而不是StringBuffer,则类“immudemo”将是不可变的


附加:按照此策略自己定义不可变对象:

YaxitaShah,在本例中,StringBuffer声明为final,但StringBuffer引用通过immudemo类中的getter方法传递

也许你可以:

final类immudemo
{
私有静态最终StringBuffer bf=新StringBuffer(“Yaxita”);
公共StringBuffer getter(){
返回新的字符串缓冲区(bf);
}
公共字符串toString(){
返回bf.toString();
}
}
公共类HelloWorld{
公共静态void main(字符串参数[])
{
immudemo obj1=新的immudemo();
StringBuffer bf2=obj1.getter();
bf2.附加(“沙阿”);
系统输出打印项次(obj1);
}

}
YaxitaShah,在本例中,StringBuffer声明为final,但StringBuffer引用通过immudemo类中的getter方法传递

也许你可以:

final类immudemo
{
私有静态最终StringBuffer bf=新StringBuffer(“Yaxita”);
公共StringBuffer getter(){
返回新的字符串缓冲区(bf);
}
公共字符串toString(){
返回bf.toString();
}
}
公共类HelloWorld{
公共静态void main(字符串参数[])
{
immudemo obj1=新的immudemo();
StringBuffer bf2=obj1.getter();
bf2.附加(“沙阿”);
系统输出打印项次(obj1);
}
}
在上面的代码中,即使StringBuffer声明为final,我也能够 改变它

不,
append()
并没有创建您的
Stringbuffer
的新对象,它只是修改相同引用对象的值

参见java文档,其中说

一旦分配了最终变量,它总是包含相同的变量 价值如果最终变量包含对对象的引用,则 对象的状态可以通过对对象的操作来更改,但是 变量将始终引用同一对象

所以,不可变类可以通过

  • 将该类声明为final,以使其无法扩展
  • 将所有字段设置为私有,以便不允许直接访问
  • 不要为变量提供setter方法
  • 将所有可变字段设为最终字段,以便其值只能指定一次
  • 通过执行深度复制的构造函数初始化所有字段
  • 在getter方法中执行对象克隆以返回副本,而不是返回实际的对象引用
在上面的代码中,即使StringBuffer声明为final,我也能够 改变它

不,
append()
并没有创建您的
Stringbuffer
的新对象,它只是修改相同引用对象的值

参见java文档,其中说

一旦分配了最终变量,它总是包含相同的变量 价值如果最终变量包含对对象的引用,则 对象的状态可以通过对对象的操作来更改,但是 变量将始终引用同一对象

所以,不可变类可以通过

  • 将该类声明为final,以使其无法扩展
  • 将所有字段设置为私有,以便不允许直接访问
  • 不要为变量提供setter方法
  • 将所有可变字段设为最终字段,以便其值只能指定一次
  • 通过执行深度复制的构造函数初始化所有字段
  • 在getter方法中执行对象克隆以返回副本,而不是返回实际的对象引用

要使StringBuilder类成为不可变的,请检查下面的类testSB实例变量,将getter方法的返回类型定义为StringBuilder,但在内部作为字符串对象进行维护

public class ImmutableClass {

    private final int value;
    private final String name;
    private final StringBuilder name1;
    private final String testSB;

    // changed the constructor, to say Immutable, instead of mutable
    public ImmutableClass( int aValue,  String aName,  StringBuilder aName1,StringBuilder aTestSB) {
        // The value is set. Now, and forever.
        value = aValue;
        name1=aName1;
        name=aName;
        testSB=new String(aTestSB);
    }

    public StringBuilder getTestSB() {
        return new StringBuilder(testSB);
    }

    public String getName() {
        return name;
    }

    public StringBuilder getName1() {
        return name1;
    }

    public final int getValue() {
        return value;
    }

}

要使StringBuilder类成为不可变的,请检查下面的类testSB实例变量,将getter方法的返回类型定义为StringBuilder,但在内部维护为String对象

public class ImmutableClass {

    private final int value;
    private final String name;
    private final StringBuilder name1;
    private final String testSB;

    // changed the constructor, to say Immutable, instead of mutable
    public ImmutableClass( int aValue,  String aName,  StringBuilder aName1,StringBuilder aTestSB) {
        // The value is set. Now, and forever.
        value = aValue;
        name1=aName1;
        name=aName;
        testSB=new String(aTestSB);
    }

    public StringBuilder getTestSB() {
        return new StringBuilder(testSB);
    }

    public String getName() {
        return name;
    }

    public StringBuilder getName1() {
        return name1;
    }

    public final int getValue() {
        return value;
    }

}

呃,使用String而不是Stringbuffer?我的意思是,这就是Stringbuffer的要点,与普通字符串相比,它是可变的。编辑:Apar