java中是否有只读字段(可在类本身的范围内设置)?

java中是否有只读字段(可在类本身的范围内设置)?,java,readonly,Java,Readonly,我们怎么能有一个在类内可写但在类外只能“可读”的变量 例如,不必这样做: Class C { private int width, height; int GetWidth(){ return width; } int GetHeight(){ return height; } // etc.. 我想这样做: Class C { public_readonly int width, height; // etc... 最好的解决方案是什

我们怎么能有一个在类内可写但在类外只能“可读”的变量

例如,不必这样做:

Class C {
  private int width, height;

  int GetWidth(){
    return width;
  }

  int GetHeight(){
    return height;
  }

  // etc..
我想这样做:

Class C {
  public_readonly int width, height;

  // etc...

最好的解决方案是什么?

在Java中无法做到这一点

您的两个选项(您提到的一个)是使用公共getter并将字段设置为私有,或者在类中使用完整的文档

getter方法的开销非常小(如果有的话)。如果要多次执行此操作,可能需要缓存获取的值,而不是调用get方法

编辑:


一种方法是使用构造函数定义一个公共的内部类(我们称之为
innerC
),该构造函数只对
C
类可用,并将字段公开,尽管它的开销比getter还要大。这样,您就无法在类外部创建
innerC
实例,因此无法从外部更改字段,但您可以从内部更改字段。但是,您可以从外部读取它们。

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

实际上,热点编译器很可能会对getter进行内联调用,因此不会涉及开销(此外,调用这些方法的开销很难测量)

编辑

如果你真的需要每个CPU周期,使用C或C++(或者写性能关键部分,通过JNA调用它,虽然它不值得花掉时间)。 据我所知,编译器不会优化这种代码

热点JIT编译器

我想知道最好的解决办法是什么

停止过早地优化。如果在绘制例程中使用此代码,我可以保证实际绘制所需时间至少是调用普通方法所需时间的一百倍,即使它不是内联的。

您的解决方案是: 私人领域, 二等兵,
受保护或公共getter(注意:受保护允许从同一个包以及子类进行访问)

使用
公共final
字段创建一个类。提供初始化这些字段的构造函数。这样,您的类将是不可变的,但从外部访问值时不会有开销。例如:

公共类ShortCalendar
{
公共最终int年、月、日;
公共快捷日历(日历)
{
如果(空==日历)
抛出新的IllegalArgumentException();
year=calendar.get(calendar.year);
month=calendar.get(calendar.month);
day=calendar.get(calendar.DATE);
}
}

是。。我们可以使用final关键字使变量只读


例如:
public final int id=10

顺便问一下,我们如何验证热点编译器是否内联调用?我不是100%确定,但我认为没有办法验证这一点(因为JVM是内联的,而不是编译器)。顺便说一句,我不明白你的第一句话,你的意思是JIT编译器内联调用吗?(我想知道是否有一份文件讨论了这种行为(用于验证))@Pacerier:这就是我的意思,我添加了一个链接以供确认。请注意,这是1999年的一篇文章的一部分——我相信这一功能已经出现在Hotspot的第一个版本中,它是Java1附带的。3@MichaelBorgwardt嘿,我又在想这个问题了,我想知道他们在说“避免使用getfield操作码”(),他们是否在试图减少这些东西的开销?@Pacerier:在这种情况下,代码甚至试图通过将字段复制到局部变量来避免重复访问字段。请注意,如果这确实有效果,那么使用get方法比使用直接可访问的字段做得更好。@MichaelBorgwardt-hmm是的,我想知道为什么它确实有效果,因为我认为运行时应该已经优化了这类事情(即在本地自动复制字段),不是吗?编辑完成了吗?内部类中的字段是否应该通过将其指定为final来防止从外部更改,从而使外部类成为唯一可以通过重新实例化内部类来更改值的1?即使我认为,我不确定有什么方法可以阻止C类的用户向内联存储一个引用,然后在C重新实例化内核之后重新设置内联到旧引用来设置一个新的值。也许一些说明“编辑”的代码片段可以帮助我消除困惑?没错,存储旧值会使此解决方案过时。没有考虑到这一点。innerC字段仍然可以从外部设置为null是和否。确保它是“只读”的,因为它是最终的;)但它是“内部”和“外部”的最终结果——我的意思是,它是最终结果,我还能说什么?原始问题(你读过吗?)的答案是否定的。当然,你可以设置最后一个变量一次,但是原始问题要求的是一些根本不存在的“只读自外部”关键字。而且这不是最终决定;)作者询问了一个字段,该字段只能在类本身的范围内设置。因此,我的解决方案满足这一条款。从问题的描述中,我们不知道是否有必要不断修改该字段。他明确要求解决方案,使其从外部只读。只有从外面。这就是整个问题的核心所在。作者展示的类示例是不可变对象的一个很好的例子。因此,<>代码>公共最终< <代码>是一个很好的选择。嗯,你知道我不喜欢喋喋不休地谈论某个主题。我的意图是在这里给出选项,而不是说不可能。getter几乎没有开销