简体   繁体   English

为什么有些android代码有公共字段?

[英]Why does some android code have public fields?

There are many questions and answers about using public fields in Object Oriented Programming, and most of them recommend not to use public fields for many reasons. 关于在面向对象编程中使用公共字段有很多问题和答案,并且大多数建议不要使用公共字段有很多原因。

But when I looked into Android's code I found some classes are using public fields. 但是当我查看Android的代码时,我发现一些类正在使用公共字段。 For example Android.view.View has public fields mCachingFailed and mAttributes . 例如, Android.view.View具有公共字段mCachingFailedmAttributes

Why are they public? 他们为什么公开? It is hard to think this is a mistake on Google and AOSP's part. 很难想象这是谷歌和AOSP的错误。

It isn't inherently a mistake to have public fields. 拥有公共领域本身并不是一个错误。 It is not, as the bounty note suggests, an "OOP-fundamental-violation". 正如赏金记录所暗示的那样,并非“OOP基本违规”。 After all these two classes are (for most purposes) identical: 毕竟这两个类(大多数用途)相同:

public class DemoA {
  public int field;
}

public class DemoB {
  private int field;

  public int getField() { return field; }
  public void setField(int value) { field = value; }
}

That is to say, if you intend for callers to have direct read and write access to a field adding a getter and setter may just be extra boiler-plate. 也就是说,如果你打算让调用者对字段有直接的读写访问权限,那么添加一个getter和setter可能只是额外的样板。

The benefit of getters and setters, even if they do no other work than reading and writing to fields, is that they abstract the fact that the data is stored in a field at all. 即使除了读取和写入字段之外没有其他工作,getter和setter的好处是它们抽象出数据存储在字段中的事实。 It could be stored in an external data source, or computed on the fly, or whatever you'd like, and callers don't have to worry about how the behavior is implemented. 它可以存储在外部数据源中,也可以动态计算,或者任何你想要的,并且调用者不必担心行为是如何实现的。 This is definitely a good practice in general because it separates the callers concerns (the API) from your concerns (the implementation). 这通常是一种很好的做法因为它将调用者关注点(API)与您的关注点(实现)分开。

However sometimes it's just overkill, and it's perfectly reasonable to expose public fields if that's the best way to provide the behavior your callers need. 然而,有时它只是矫枉过正,如果这是提供调用者所需行为的最佳方式,那么暴露公共字段是完全合理的。 Most often, this is done for value types , classes that exist solely to group a number of fields together. 大多数情况下,这是做价值类型 ,即存在只是为了组若干领域的共同类。 There's little benefit to writing out scores of getters and setters when everything you need a class to do can be accomplished by simply making the fields public. 当你需要上课时所做的一切都可以通过简单地公开领域来完成,写出几十个吸气剂和制定者几乎没有什么好处。

As a practical matter, Android has an additional concern. 实际上,Android还有一个额外的问题。 Method calls are expensive and the number of methods an app can (easily) define is limited to ~65k . 方法调用很昂贵,应用程序可以(轻松)定义的方法数量限制为~65k For cases where it's safe to do so, exposing a field directly reduces the method overhead by two and saves valuable CPU time. 对于可以安全执行此操作的情况,直接暴露字段可将方法开销减少两倍,从而节省宝贵的CPU时间。 That might not seem like a lot, but it adds up quickly. 这可能看起来不是很多,但它很快就会增加。

Check out this section from developer.android.com: 从developer.android.com查看此部分:

In native languages like C++ it's common practice to use getters (i = getCount()) instead of accessing the field directly (i = mCount). 在像C ++这样的本地语言中,通常的做法是使用getter(i = getCount())而不是直接访问字段(i = mCount)。 This is an excellent habit for C++ and is often practiced in other object oriented languages like C# and Java, because the compiler can usually inline the access, and if you need to restrict or debug field access you can add the code at any time. 这是C ++的一个很好的习惯,并且经常用于其他面向对象的语言,如C#和Java,因为编译器通常可以内联访问,如果您需要限制或调试字段访问,您可以随时添加代码。

However, this is a bad idea on Android. 但是,这在Android上是一个坏主意。 Virtual method calls are expensive, much more so than instance field lookups. 虚拟方法调用比实例字段查找要昂贵得多。 It's reasonable to follow common object-oriented programming practices and have getters and setters in the public interface, but within a class you should always access fields directly. 遵循常见的面向对象编程实践并在公共接口中使用getter和setter是合理的,但在类中,您应该始终直接访问字段。

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. 没有JIT,直接字段访问速度比调用一个简单的getter快约3倍。 With the JIT (where direct field access is as cheap as accessing a local), direct field access is about 7x faster than invoking a trivial getter. 使用JIT(直接字段访问与访问本地一样便宜),直接字段访问比调用一个简单的getter快约7倍。

Note that if you're using ProGuard, you can have the best of both worlds because ProGuard can inline accessors for you 请注意,如果您正在使用ProGuard,那么您可以充分利用这两个领域,因为ProGuard可以为您提供内联访问器

http://developer.android.com/training/articles/perf-tips.html#GettersSetters http://developer.android.com/training/articles/perf-tips.html#GettersSetters

Most likely, this is the reason you see public fields in AOSP. 最有可能的是,这就是您在AOSP中看到公共字段的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM