Skip to content

[问答]声明ViewHolder内部类时,为什么建议使用static关键字 #65

Open
@licheedev

Description

@licheedev

RT

Activity

changed the title [-]声明ViewHolder时,为什么建议使用static关键字[/-] [+][问答]声明ViewHolder时,为什么建议使用static关键字[/+] on Mar 13, 2015
stackvoid

stackvoid commented on Mar 13, 2015

@stackvoid

个人觉得,使用 static 关键字,一般都在内部类里面,这样就可以解除与当前类的关系。
如果单独写一个 ViewHolder 类,完全可以不用 static。

changed the title [-][问答]声明ViewHolder时,为什么建议使用static关键字[/-] [+][问答]声明ViewHolder内部类时,为什么建议使用static关键字[/+] on Mar 13, 2015
SoftwareME

SoftwareME commented on Mar 13, 2015

@SoftwareME

holder = new ViewHolder();
不会重新分配内存空间,节省内存?

licheedev

licheedev commented on Mar 13, 2015

@licheedev
Author

@SoftwareME 你这样不对吧,只要new对象出来,就一定会分配内存给new出来的对象,就算这个对象的类使用static声明的。
之前好像看过,貌似是用static声明的内部类,编译的时候是跟外部类同一级别的,如果不用static声明,内部类会持有外部类对象的引用。不过不太确定,一直没怎么注意编译层次的问题。

licheedev

licheedev commented on Mar 13, 2015

@licheedev
Author

好了,翻了下跟朋友的聊天记录,翻出来之前看过的文章了。
http://klcwt.iteye.com/blog/452834
下面这篇更详细点
http://blog.sina.com.cn/s/blog_77c6324101016hgm.html

dkmeteor

dkmeteor commented on Mar 13, 2015

@dkmeteor
Member

一句话总结回答:

非静态内部类隐式持有外部类的强引用。


感兴趣的可以自己写一个非静态内部类,编译成class,再反编译就可以看到内部类隐式持有的this$0对象

dkmeteor

dkmeteor commented on Mar 14, 2015

@dkmeteor
Member

@xyczero

你指的是ClassLoader的类加载?我不是很明白...非静态内部类难道会加载多次?

xyczero

xyczero commented on Mar 15, 2015

@xyczero

@dkmeteor
我想错了=。=,已删掉

mxn21

mxn21 commented on Mar 16, 2015

@mxn21

用static定义的静态内部类相对独立,不能访问所在类的方法和实体,占用资源更少。如果去掉static,可以彼此互相访问实体,会略微浪费一些资源。

Rowandjj

Rowandjj commented on Mar 17, 2015

@Rowandjj

主要是防止内存泄露

xyczero

xyczero commented on Mar 17, 2015

@xyczero

@Rowandjj
我觉得这里使用Static ViewHolder和内存泄露没关系吧,除非你在adapter里声明了一个static 变量=。=

szuwest

szuwest commented on Mar 19, 2015

@szuwest

这个问题也是我每次面试别人必问的问题之一。其实这个是考静态内部类和非静态内部类的主要区别之一。非静态内部类会隐式持有外部类的引用,就像大家经常将自定义的adapter在Activity类里,然后在adapter类里面是可以随意调用外部activity的方法的。当你将内部类定义为static时,你就调用不了外部类的实例方法了,因为这时候静态内部类是不持有外部类的引用的。声明ViewHolder静态内部类,可以将ViewHolder和外部类解引用。大家会说一般ViewHolder都很简单,不定义为static也没事吧。确实如此,但是如果你将它定义为static的,说明你懂这些含义。万一有一天你在这个ViewHolder加入一些复杂逻辑,做了一些耗时工作,那么如果ViewHolder是非静态内部类的话,就很容易出现内存泄露。如果是静态的话,你就不能直接引用外部类,迫使你关注如何避免相互引用。 所以将 ViewHolder内部类 定义为静态的,是一种好习惯

kyangc

kyangc commented on Mar 19, 2015

@kyangc

学习了……

frankpi

frankpi commented on Mar 19, 2015

@frankpi

受益了;

4 remaining items

Rowandjj

Rowandjj commented on Mar 23, 2015

@Rowandjj

@xyczero
非静态内部类隐式持有外部类的强引用,如果不加static,将会导致内存泄露。

xyczero

xyczero commented on Mar 23, 2015

@xyczero

@Rowandjj
非静态内部类隐式持有外部类的强引用,只是可能会导致内存泄露,而一般情况下在使用viewhodler是不会导致内存泄露的,加staticw是一个比较好的习惯,我比较赞同 @szuwest 的观点
好吧,我承认我有点咬文嚼字,别介意哈=。=

dkmeteor

dkmeteor commented on Mar 23, 2015

@dkmeteor
Member

@Rowandjj @xyczero
我认为正确使用ViewHolder的话,是否加static都不会造成内存泄露.
因为ViewHolder的生命周期一般比Adaper要短.

@szuwest 说的,如果你在ViewHolder内做一些耗时操作,比如开启一个线程,导致了内存泄露,那么泄露的原因是 你不应当在ViewHolder中做这样的操作,而不是你没有将ViewHolder声明成Static

我现在有点怀疑这个问题是个陷阱,因为我能想出来的泄露写法都是非常奇葩的写法.

xingty

xingty commented on Mar 23, 2015

@xingty

@dkmeteor
同意你的观点。内部类内存泄漏的情况其实很少,即便是handler,只要不延迟操作,就不会有内存泄漏问题。

liulinru13

liulinru13 commented on May 20, 2015

@liulinru13

之前看 java编程思想 内部类这块的时候,似懂非懂,但是没有和viewHolder是否是static联系起来,@szuwest 感谢指点!

ronanhardiman

ronanhardiman commented on May 20, 2015

@ronanhardiman

@szuwest 说的很详细.

LandChanning

LandChanning commented on Mar 3, 2016

@LandChanning

@szuwest 那静态内部类的会影响该对象的垃圾回收吗

diov

diov commented on Mar 8, 2016

@diov

@jp1017 我觉得小黑屋里讲的跟这个情况还有些不同。一般我们使用Handler都是需要进行异步的操作,后台运行。这个时候如果对外部类有强引用很容易出线泄露
而adapter中很少会有这种需求。这个问题我面试的时候也碰到过,不过问得是对性能有没有影响

dxjia

dxjia commented on Mar 8, 2016

@dxjia

@diov 性能方面会有什么区别吗?

diov

diov commented on Mar 11, 2016

@diov

@dxjia 对性能是有影响的,特别是初始化adapter的时候。
why in ViewHolder pattern should the ViewHolder class be static?

lusccc

lusccc commented on Apr 7, 2016

@lusccc

受益了,前几天面阿里刚好答反了😂

xiaojianchen

xiaojianchen commented on Nov 18, 2016

@xiaojianchen
xiaojianchen

xiaojianchen commented on Nov 18, 2016

@xiaojianchen

The simplest form of inner class

  • Can’t have the same name as the enclosing class
  • Compiled into a completely separate .class file from the outer class
  • Can access only static members and methods of the enclosing class, including private static members
  • Create an instance of a static inner class out of enclosing class: new outerclass.innerclass()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @ronanhardiman@szuwest@xingty@xiaojianchen@Lighted

        Issue actions

          [问答]声明ViewHolder内部类时,为什么建议使用static关键字 · Issue #65 · android-cn/android-discuss