1.关于viewHolder设置成static的讨论

一般情况下是尽量不要使用static关键字,因为static一旦有引用变量指向了变量,使用完毕后而没有设置null,就会造成内存泄露,而且很难排查。但并非绝对不允许使用static,你需要非常小心的维护这个static的引用。

这里要讨论的是在listView优化时,使用的viewHolder,这个类Google的示例程序将该类定义为静态内部类,是因为它没有依赖任何外部类,它本身是独立的,不会存在内存泄漏。更为详细的解释如下:

(1)一般来说,我们声明为静态嵌套类,当它没有依赖外部类。在我们的例子中,ViewHolder类从未引用(访问)适配器类的任何成员变量(外部类),因此我们可以声明为静态的。保持简单nested-static类只是另一个(外)类是嵌套的可读性,因为它的使用仅限于只有它的外部类。你必须宣布非静态嵌套类(称为内部类)如果访问外部类的成员变量。

(2)《Effective Java》第22条 优先考虑静态成员类 其中有条建议: 如果声明成员类不要求访问外围实例,就要始终把static修饰符放在它的声明中,使它成为静态成员类,而不是非静态成员类。 因为非静态成员类的实例会包含一个额外的指向外围对象的引用,保存这份引用要消耗时间和空间,并且导致外围类实例符合垃圾回收时仍然被保留。如果没有外围实例的情况下,也需要分配实例,就不能使用非静态成员类,因为非静态成员类的实例必须要有一个外围实例。

PS:强烈推荐《Effective Java》这本书,会让你有意想不到的收获。http://www.jianshu.com/p/be247a4cf359

(3)这篇文章中没有提到加载时机的问题吧。在我的理解中:静态内部类主要作用就是,内部类是否需要隔离“外部类的this对象(指针)”。内部类是有 this 指针的,可以“直接”访问外部类的 成员变量和成员函数(包括私有的成员)。而静态内部类,没有这个this指针,所以无法“直接”调用。  Android代码中,经常使用的Builder,LayoutParams都是以静态内部类的方式存在啊。我们可以根据实际使用情况来效仿。  对于这篇文章,我理解。ViewHolder的构造和复用,与静不静态没关。核心是ListView(AdapterView),通过getView(int position, View convertView, ViewGroup parent) 的convertView会为开发者传入一个可以复用的对象。开发者需要利用该对象,减少应用内存的消耗。 如果从减少内存消耗的角度来开。我认为ViewHolder还是应该修饰成static比较好。这样ViewHolder中可以减少MainActivity的this指针,由于减少了一个this指针的引用,也会对MainActivity的引用计数大大减少。MainActivity的this指针继承于android的Context上下文,对于Context的回收遗漏,是Android内存管理中很大的问题。我们减少了对Context的引用,可以更容易减少Context引用计数出现问题。

(4)stackoverflow相关解答:https://stackoverflow.com/questions/13516835/why-in-viewholder-pattern-should-the-viewholder-class-be-static

2. java为什么会有静态抽象类?继承静态(内部)抽象类时发生了什么?

public class RecyclerView extends ViewGroup implements ScrollingView, NestedScrollingChild
{
.......
public static abstract class ViewHolder {...}
......
}

静态内部类和定义一个普通的类没啥区别,只不过静态内部类是定义在另一个类内部了。   继承内部静态抽象类,也没啥特别的事发生。

首先 static 只能用来修饰类的成员,所以顶级类不能用 static 修饰。

所以 static class 一定是一个内部类,即静态内部类。

静态内部类与外部类之间并没有任何关系,其外部类仅仅起到一个名字空间的作用,和包名起差不多的作用。而静态内部类也不持有外部类的引用,也不能引用外部类的private成员。  一个静态内部类其实是具有顶级类的地位,那么和一般的抽象类其实并没有什么不同。

3. java中抽象类为什么不能定义为static型?

一般分两个阶段

阶段一:先载入类

阶段二:然后才能依据类来实例化对象 而static的方法、变量都是属于类的,非static的则属于对象

如果在阶段一,访问非static的方法,因为还没有对象,所以不能访问成功

如果在阶段二,一个类有那么多对象在内存生存着,类也不知道该访问哪个对象的实例变量

4. 外部抽象类不能用static修饰

static的用法:
  1、static 关键字:可以用于修饰属性,也可以用于修饰方法,还可以用于修饰类。
  2、static 修饰属性:无论一个类生成了多少个对象,所有这些对象共同使用唯一一份静态的成员变量;一个对象对该静态成员变量进行了修改,其他对象的该静态成员变量的值也会随之发生变化。如果一个成员变量是static 的,那么我们可以通过 类名 .成员变量名 成员变量名 成员变量名 的方式来使用它 的方式来使用它 (推荐使用这种方式) 。
  3、static修饰方法: static 修饰的方法叫做静态。 对于静态方法来说,可以 使用 类名 .方法名的方式来访问。
  4、静态方法只能继承,不重写(Override)
  5、不能在静态方法中访问非静态成员变量;
  6、不能在静态方法中使用this关键字。

7、静态内部类是可以用static修饰的

5.不可以和抽象abstract关键字共存的关键字

1).private :因为一个abstract方法需要被重写,所以不能修饰为private;

 2).final:因为一个abstract方法需要被重写。被final修饰的方法是不能被重写的,所以不能同final共存;
 3).static:因为一个abstract方法没有方法体。静态方法需要对方法体执行内容分配空间,所以不能同static共存;(abstract是没有实现的,不能产生对象,而是static是属于类的,类本身是已经存在的对象)
 4).synchronized: 是同步的,然而同步需要具体的操作才能同步,但, abstract是只有声明没有实现的(即,使用synchronized关键字的是需要有具体的实现同步的操作的,但是使用abstract是只有声明而没有实现的,这样就产生了冲突)
 5).native:他们本身的定义就是冲突的,native声明的方法是移交本地操作系统实现的,而abstract是移交子类对象实现的,同时修饰的话,导致不知道谁实现声明的方法

201709013工作日记--static理解 && abstract的更多相关文章

  1. 201709013工作日记--Android消息机制HandlerThread

    1.首先来看一个常规的handler用法: 在主线程中建立一个handler: private Handler mHandler = new Handler() { @Override public ...

  2. 201709013工作日记--Android异步通信AsyncTask

    参考相关博客:http://blog.csdn.net/liuhe688/article/details/6532519 在Android中实现异步任务机制有两种方式,Handler和AsyncTas ...

  3. 学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat

    学完微型服务器(Tomcat)对其工作流程的理解,自己着手写个简单的tomcat 2019-05-09   19:28:42 注:项目(MyEclipse)创建的时候选择:Web Service Pr ...

  4. 修饰符static和abstract

    修饰符static和abstract static static可以修饰类中的方法,属性等,被修饰后的方法和属性可以通过类名直接调用也可以通过对象调用.普通的变量只能通过对象进行调用. 静态方法直接可 ...

  5. 一张图看懂normal,static,sealed,abstract 的 区别

    +-------------------------+---+--------+--------+--------+----------+ | Class Type | | normal | stat ...

  6. 深入理解abstract class和interface(转)

    原文地址 深入理解abstract class和interface java提高篇(四)-----抽象类与接口

  7. final,static,abstract

    一.final 1.可以修饰属性,表示常量,其值在运行期间不允许改变.常量必须赋初始值,初始值可以在声明出,构造方法的任意一个地方赋 优点:增强程序的可读性,可维护性 2.可以修饰方法,表示该方法不能 ...

  8. 浅析java修饰符之public default protected private static final abstract

    浅析java修饰符之public default protected private static final abstract 一   修饰符的作用:用来定义类.方法或者变量,通常放在语句的最前端 ...

  9. Java中 final、static、abstract区别与联系

    1.static修饰符 static作用于代码块:称作静态代码块(可以初始化static field,不能初始化非static field); static作用于methods: static方法只能 ...

随机推荐

  1. Mysql 知识(1)

    1. 请简洁地描述下MySQL中InnoDB支持的四种事务隔离级别名称,以及逐级之间的区别? 答: SQL标准定义的四个隔离级别为:read uncommited,read committed,rep ...

  2. Rust语言学习笔记(4)

    Variables and Mutability(变量和可变性) 变量声明有三种:不变量(运行期的常量),变量以及(编译期的)常量. 变量可以重复绑定,后声明的变量覆盖前面声明的同名变量,重复绑定时可 ...

  3. 练习:自己写一个容器ArrayList集合 一一数组综合练习2

    package cn.bjsxt.collection; /** * 自己实现一个ArrayList */ import java.util.ArrayList; import java.util.L ...

  4. 《Blue Flke》第一次作业:团队亮相

    1.队名:Blue Flke 团队格言:决心是成功的力量,耐心是成功的保障. 2.团队成员组成:  201571030129/ 王胜海 (组长)  201571030126/ 妥志福 20157103 ...

  5. python复制文件,路径不存在问题(Windows和linux路径分隔符不统一)

    问题: python脚本涉及到复制文件,而我们需要兼容Windows.linux和mac环境 (Windows和linux的路径分隔符不同:通过os.path.sep查看分隔符)   如果用[路径名+ ...

  6. 等待时间,time.sleep()和implicitly_wait()

    在运行一个以前执行的过的功能时,报错了,不能执行了. 功能描述:通过导航,选择下拉项(发布职位功能),下面是审查的元素: 获取元素的代码: 尝试了用xpath去获取:driver.find_eleme ...

  7. nat 类型及打洞原理

    nat 类型分4种 1.全锥形 full cone A 与 主机B交互,nat转换 A的内部地址及端口为  ip1 port1,ip1和port1为对外地址,任何机器能访问. 2.ip 受限制(对B而 ...

  8. Ubuntu 16.04安装Git及GUI客户端

    1.通过APT源安装Git命令行工具 这里不建议通过源码进行安装,增加复杂程度,且最新版本的Git在各个方面都会修复,不至于出现不能用的状态. sudo add-apt-repository ppa: ...

  9. OpenCL、OpenGL、OpenAL

    一:OpenCL (全称Open Computing Language,开放运算语言)是第一个面向异构系统通用目的并行编程的开放式.免费标准,也是一个统一的编程环境,便于软件开发人员为高性能计算服务器 ...

  10. 关于Python的OSError和IOError

    参考:http://stackoverflow.com/questions/29347790/difference-between-ioerror-and-oserror 在3.x版本已经移除,剩下O ...