简体   繁体   中英

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. For example Android.view.View has public fields mCachingFailed and mAttributes .

Why are they public? It is hard to think this is a mistake on Google and AOSP's part.

It isn't inherently a mistake to have public fields. It is not, as the bounty note suggests, an "OOP-fundamental-violation". 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.

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. 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).

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. Method calls are expensive and the number of methods an app can (easily) define is limited to ~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. That might not seem like a lot, but it adds up quickly.

Check out this section from 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). 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.

However, this is a bad idea on 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.

Without a JIT, direct field access is about 3x faster than invoking a trivial getter. 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.

Note that if you're using ProGuard, you can have the best of both worlds because ProGuard can inline accessors for you

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

Most likely, this is the reason you see public fields in AOSP.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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