Java 为什么 Android 更喜欢静态类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3106912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 16:29:56  来源:igfitidea点击:

Why does Android prefer static classes

javaandroidperformancestatic-classes

提问by Jeremy Edwards

I see a lot of java code where android prefers to have developers use static inner classes. Particularly for patterns like the ViewHolder Patternin custom ListAdapters.

我看到很多 java 代码,其中 android 更喜欢让开发人员使用静态内部类。特别是对于像自定义 ListAdapter 中的ViewHolder 模式这样的模式

I'm not sure what the differences are between static and non-static classes. I've read about it but it doesn't seem to make sense when concerned with performance or memory-footprint.

我不确定静态和非静态类之间有什么区别。我读过它,但在关注性能或内存占用时似乎没有意义。

采纳答案by gustafc

It's not just Android developers...

不仅仅是 Android 开发者...

A non-static inner class always keeps an implicit reference to the enclosing object. If you don't need that reference, all it does is cost memory. Consider this:

非静态内部类始终保持对封闭对象的隐式引用。如果您不需要该参考,它所做的就是消耗内存。考虑一下:

class Outer {
    class NonStaticInner {}
    static class StaticInner {}
    public List<Object> foo(){ 
        return Arrays.asList(
            new NonStaticInner(),
            new StaticInner()); 
    }
}

When you compile it, what you get will be something like this:

当你编译它时,你得到的将是这样的:

class Outer {
    Outer(){}
    public List<Object> foo(){ 
        return Arrays.asList(
            new Outer$NonStaticInner(this),
            new StaticInner()); 
    }
}
class Outer$NonStaticInner {
    private final Outer this
class Outer{
    class Inner{//Only works with non static inner class
          public Outer getOuter(){return Outer.this;}
    }
}
; Outer$NonStaticInner(Outer enclosing) { this
Outer.Inner in = new Outer().new Inner();
= enclosing; } } class Outer$StaticInner { Outer$StaticInner(){} }

回答by Viliam

Static inner classes (i.e. classes declared inside another class with keyword static) are quite similar to "normal" classes except you don't pollute your package's name space. That is their (only) difference and benefit and I believe that's the reason you see it in Android.

静态内部类(即在另一个类中使用关键字声明的类static)与“普通”类非常相似,只是您不会污染包的名称空间。这是他们(唯一)的区别和好处,我相信这就是您在 Android 中看到它的原因。

Use static inner classes when the purpose of the class is tighten to the main class, but does not depend on its instances. This is generally considered as a good practice.

当类的目的与主类紧密相关但不依赖于其实例时,请使用静态内部类。这通常被认为是一种很好的做法。

回答by Jere.Jones

The main difference between static and non-static inner classes is that a non-static inner class has access to other members of the outer class, even if they are private. Non-static inner classes are a "part" of the outer class. You cannot create nor can they exist without an instance of an outer class. A consequence of this is that an instance of a non-static inner classes are destroyed when the outer class's instance is destroyed.

静态和非静态内部类之间的主要区别在于,非静态内部类可以访问外部类的其他成员,即使它们是私有的。非静态内部类是外部类的“一部分”。如果没有外部类的实例,您将无法创建,也不能存在它们。这样做的结果是,当外部类的实例被销毁时,非静态内部类的实例也会被销毁。

Static inner classes, on the other hand, are just like normal outer classes. The live and die on their own. You don't need an instance of the outer class for the inner class to exist. That means they also have their own life cycle. They get destroyed when the garbage collector decides to destroy them.

另一方面,静态内部类就像普通的外部类。生死自己。您不需要外部类的实例来存在内部类。这意味着它们也有自己的生命周期。当垃圾收集器决定销毁它们时,它们就会被销毁。

How does this affect memory and/or performance? I really don't know. :)

这如何影响内存和/或性能?我真的不知道。:)

回答by shoren

If you decompile an inner class (or watch it using debugger) you can see that there is generated code for accessing the instance of the outer class that was used to create them. The overhead for this is more memory for the additional pointer, more cpu for garbage collection because of additional pointer to test, and if you want to nit pick, longer compile time. Creating instances of non static inner classes is a bit more complicated because you need an instance of the outer class to create them.

如果您反编译一个内部类(或使用调试器观察它),您可以看到生成的代码用于访问用于创建它们的外部类的实例。这样做的开销是额外指针的更多内存,由于额外的要测试的指针而导致垃圾收集更多的 cpu,并且如果您想选择 nit 选择,则需要更长的编译时间。创建非静态内部类的实例有点复杂,因为您需要一个外部类的实例来创建它们。

Visibility of both static and non-static inner classes can be controlled. Usually they are private if their implementation is strongly connnected to internal details of the outer class, and the developer doesn't think the code can be reused. In this sense they are not better than private functions. Inner classes might be public in cases like Map.Entry, where the inner class is strongly connected to the interface exposed by the class, and the developer doesn't think that Map.Entry can be used without some kind of a Map. Both types have access to private members of the outer class and the outer class has access to private members of the inner class.

可以控制静态和非静态内部类的可见性。通常,如果它们的实现与外部类的内部细节密切相关,并且开发人员认为代码不能重用,则它们是私有的。从这个意义上说,它们并不比私有函数好。在像 Map.Entry 这样的情况下,内部类可能是公共的,在这种情况下,内部类与类公开的接口紧密相连,开发人员认为没有某种 Map 就不能使用 Map.Entry。这两种类型都可以访问外部类的私有成员,而外部类可以访问内部类的私有成员。

Instances of static and non-static inner classes are garbage collected like every other class. There is no special connection between the grabage collection of the outer class and the garbage collection of the inner class.

静态和非静态内部类的实例像其他所有类一样被垃圾收集。外部类的垃圾回收和内部类的垃圾回收之间没有特殊的联系。

In the case of UI classes implementation like swing or android you will see static inner classes because they are treated like private function. These classes are not developed for reusability outside the outer class and are strongly connected to the internal implementation of the outer class. There is no reason to expose them and to make sure they can work in more cases than the specific context of the outer class requirements.

在 UI 类实现(如 Swing 或 android)的情况下,您将看到静态内部类,因为它们被视为私有函数。这些类不是为了外部类之外的可重用性而开发的,并且与外部类的内部实现密切相关。没有理由公开它们并确保它们可以在比外部类要求的特定上下文更多的情况下工作。

回答by josefx

A non static inner class instance holds a reference to the outer class instance while a static inner class instance does not.

非静态内部类实例持有对外部类实例的引用,而静态内部类实例则没有。

This is relevant for the applications memory footprint as the hidden reference may lead to memory leaks - the garbage collector cannot collect the outer class instance until no more references exist. Also the additional reference itself needs memory, this may be relevant if a high number of instances are used.

这与应用程序内存占用相关,因为隐藏引用可能导致内存泄漏 - 垃圾收集器无法收集外部类实例,直到不再存在引用。此外,附加引用本身也需要内存,如果使用大量实例,这可能是相关的。

##代码##

It is also relevant for its use, the reference to the outer class is a ctor argument of the inner class, to create a new non static inner class object you have to call the ctor like a memberfunction on an instance of the outer class or from within a memberfunction of the outer class. This means that you cannot have a instance of the inner class without an instance of the outer class.

它也与其使用相关,对外部类的引用是内部类的 ctor 参数,要创建新的非静态内部类对象,您必须像外部类实例上的成员函数一样调用 ctor 或从在外部类的成员函数中。这意味着如果没有外部类的实例,就不能拥有内部类的实例。

##代码##