我们在java中有一个Readonly字段(可以在类本身的范围内设置)吗?

Pac*_*ier 37 java readonly

我们怎样才能拥有一个在类中可写的变量,但只能在其外部"可读"?

例如,而不是必须这样做:

Class C {
  private int width, height;

  int GetWidth(){
    return width;
  }

  int GetHeight(){
    return height;
  }

  // etc..
Run Code Online (Sandbox Code Playgroud)

我想做这样的事情:

Class C {
  public_readonly int width, height;

  // etc...
Run Code Online (Sandbox Code Playgroud)

什么是最好的解决方案?

Ale*_* N. 40

创建一个包含public final字段的类.提供构造函数,以初始化这些字段.这样你的类将是不可变的,但是你不会有从外部访问值的开销.例如:

public class ShortCalendar
{
    public final int year, month, day;

    public ShortCalendar(Calendar calendar)
    {
        if (null == calendar)
            throw new IllegalArgumentException();

        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DATE);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 首先,我并不反对在真正需要的地方使用吸气剂.通常他们只是使用样板oneliner膨胀你的代码.Java是一种笨拙的语言,幸运的是,有一小部分案例可以让你获得像Objective C属性一样优雅的东西. (8认同)
  • Getters几乎没有Java的开销.该语言专为此类编程而设计,旨在处理大量的getter.简单的getter(大多数getter都是)将由JVM优化,提供几乎本机代码的访问速度. (2认同)
  • @AlaksiejN.,如果你需要在对象构建后修改类中的值,这个解决方案不起作用...... (2认同)
  • @Pacerier 是的,这是预期的行为。如果您需要一个比 C 结构(远)复杂的类,请使用其他人的建议。 (2认同)

Luc*_*ore 18

在Java中没有办法做到这一点.

您提供的两个选项(您提到的一个选项)正在使用公共getter并将该字段设为私有,或者在类中提供全面的文档.

getter方法的开销非常小(如果有的话).如果你这么做很多次,你可能想要缓存获取的值而不是调用get方法.

编辑:

一种方法,虽然它比getter有更多的开销,但是定义一个公共内部类(让我们称之为innerC)使用只对你的C类可用的构造函数,并使你的字段公开.这样,您就无法innerC在课堂外创建实例,因此无法从外部更改字段,但您可以从内部更改它们.但是你可以从外面读它们.

  • 编辑完成了吗?是否应该通过将内部类的字段指定为final来保护内部类的字段免受外部更改,从而使外部类成为可以通过重新实例化内部类来更改值的唯一1个字段?即使考虑到这一点,我也不确定是否有任何方法可以防止C类用户存储对innerC的引用,然后在C重新实例化innerC设置新值后将innerC重置为旧引用。也许一些说明您“编辑”的代码片段可以帮助消除我的困惑? (2认同)

Mic*_*rdt 6

据我所知,编译器不优化这种代码

Hotspot JIT编译器绝对是.

我想知道什么是最好的解决方案?

停止过早优化.如果你在绘画例程中使用这个代码,我可以保证实际绘画比调用一个简单的方法花费至少一百倍,即使它没有内联.


Tho*_*rig 5

无法从外部使字段“只读”。唯一且正确的方法是将字段设为私有并仅提供 getter,而不提供 setter。

  • 他_明确_要求一个解决方案,使其从_外部_只读。只能从外面来。这就是整个问题的目的。 (2认同)