Jer*_*rds 38 java performance android static-classes
我看到很多java代码,其中android更喜欢让开发人员使用静态内部类.特别是对于自定义ListAdapters中的ViewHolder Pattern等模式.
我不确定静态类和非静态类之间的区别.我已经读过它但是在关注性能或内存占用时似乎没有意义.
gus*_*afc 68
它不只是Android开发者......
非静态内部类始终保持对封闭对象的隐式引用.如果您不需要该引用,它所做的只是成本记忆.考虑一下:
class Outer {
class NonStaticInner {}
static class StaticInner {}
public List<Object> foo(){
return Arrays.asList(
new NonStaticInner(),
new StaticInner());
}
}
Run Code Online (Sandbox Code Playgroud)
当你编译它时,你得到的将是这样的:
class Outer {
Outer(){}
public List<Object> foo(){
return Arrays.asList(
new Outer$NonStaticInner(this),
new StaticInner());
}
}
class Outer$NonStaticInner {
private final Outer this$0;
Outer$NonStaticInner(Outer enclosing) { this$0 = enclosing; }
}
class Outer$StaticInner {
Outer$StaticInner(){}
}
Run Code Online (Sandbox Code Playgroud)
Jer*_*nes 25
静态和非静态内部类之间的主要区别在于,非静态内部类可以访问外部类的其他成员,即使它们是私有的.非静态内部类是外部类的"部分".如果没有外部类的实例,您就无法创建也无法存在.这样做的结果是,当外部类的实例被销毁时,会破坏非静态内部类的实例.
另一方面,静态内部类就像普通的外部类一样.生死攸关.您不需要外部类的实例来存在内部类.这意味着他们也有自己的生命周期.当垃圾收集器决定销毁它们时,它们会被销毁.
这对内存和/或性能有何影响?我真的不知道.:)
Vil*_*iam 15
静态内部类(即在具有关键字的另一个类中声明的类static
)与"普通"类非常相似,除非您不污染包的名称空间.这是他们(唯一)的差异和好处,我相信这就是你在Android中看到它的原因.
当类的用途收紧到主类时使用静态内部类,但不依赖于它的实例.这通常被认为是一种很好的做法.
非静态内部类实例持有对外部类实例的引用,而静态内部类实例则没有。
这与应用程序的内存占用量有关,因为隐藏的引用可能导致内存泄漏-垃圾收集器无法收集外部类实例,直到不存在更多引用为止。另外,附加引用本身也需要内存,如果使用大量实例,这可能很重要。
class Outer{
class Inner{//Only works with non static inner class
public Outer getOuter(){return Outer.this;}
}
}
Run Code Online (Sandbox Code Playgroud)
它的用法也很重要,对外部类的引用是内部类的ctor参数,要创建一个新的非静态内部类对象,您必须像在外部类的实例上或从外部实例的成员函数一样调用ctor在外部类的成员函数中。这意味着没有外部类的实例就不能拥有内部类的实例。
Outer.Inner in = new Outer().new Inner();
Run Code Online (Sandbox Code Playgroud)
如果您对一个内部类进行反编译(或使用调试器观看),则可以看到生成了用于访问用于创建它们的外部类实例的代码。这样做的开销是额外的指针需要更多的内存,由于要测试的额外指针需要更多的cpu用于垃圾回收,并且如果您想进行选择,则需要更长的编译时间。创建非静态内部类的实例要复杂一些,因为您需要外部类的实例才能创建它们。
静态和非静态内部类的可见性都可以控制。如果它们的实现与外部类的内部细节紧密联系在一起,则通常它们是私有的,并且开发人员认为代码无法重用。从这个意义上讲,它们并不比私有功能更好。内部类在诸如Map.Entry之类的情况下可能是公共的,其中内部类与该类公开的接口紧密相连,并且开发人员认为Map.Entry不能在没有某种Map的情况下使用。两种类型都可以访问外部类的私有成员,而外部类可以访问内部类的私有成员。
静态和非静态内部类的实例像其他所有类一样被垃圾回收。外部类的抓取集合与内部类的垃圾回收之间没有特殊的联系。
对于诸如swing或android的UI类实现,您将看到静态内部类,因为它们被视为私有函数。这些类不是为外部类之外的可重用性而开发的,它们与外部类的内部实现紧密相关。除了外部类要求的特定上下文之外,没有理由公开它们并确保它们可以在更多情况下工作。