JAVA整理

JAVA问题

Java中的instanceof关键字

instanceof是Java的一个二元操作符,和==,>,<是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子:

  String s = "I AM an Object!";

  boolean isObject = s instanceof Object;

newinstance()

2 序列化

Cloneable Serializable Comparable 安卓还有 Parcelable

java高级---->Serializable的过程分析

http://www.cnblogs.com/huhx/p/sSerializableTheory.html

Java序列化与反序列化详解后续

http://donald-draper.iteye.com/blog/2357891

Serializable里可以反射读取对象的数据和直接读取序列化成员变量值。

并且可以通过writeObject() readObject() 函数、 transient关键字 达到自定义序列化的目的

3 原码 反码 补码

原创 -128的二进制有原码 反码和补码

-128的源码是1000 0000 

对于负数,先取绝对值,然后求反,加一 

-128 -> 128 -> 1000 0000 -> 0111 1111 -> 1000 0000 

使用JDBC时Class.forName()的作用 

http://www.cnblogs.com/springcsc/archive/2010/03/03/1676977.html 

Class.forName(xxx.xx.xx) 返回的是一个类 

Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

5 增强循环

JAVA for 冒号 增强循环 JAVA5.0加入

6 JDB 调试JAVA程序

jdb 类名

stop at 类名:行号

locals     查看本地变量

run

step 运行下一步

next 运行到下一行

7 Strictfp 关键字

strictfp, 即 strict float point (精确浮点)。

  strictfp 关键字可应用于类、接口或方法。使用 strictfp 关键字声明一个方法时,该方法中所有的float和double表达式都严格遵守FP-strict的限制,符合IEEE-754规范。当对一个类或接口使用 strictfp 关键字时,该类中的所有代码,包括嵌套类型中的初始设定值和代码,都将严格地进行计算。严格约束意味着所有表达式的结果都必须是 IEEE 754 算法对操作数预期的结果,以单精度和双精度格式表示。

如果你想让你的浮点运算更加精确,而且不会因为不同的硬件平台所执行的结果不一致的话,可以用关键字strictfp.

8 new一个String对象占用多少内存

Java中对象的内存使用学习

http://matt33.com/2016/05/07/java-object-memory/ 

每个String对象都会使用40字节:

16字节表示对象,三个int实例变量各需4个字节,加上数组引用的8个字节和4个填充字节

String那点事儿2--占了多少空间

http://wwwiteye.iteye.com/blog/1985980 

那么一个空 String 所占空间为:

8(对象开销) + 12字节(3个int) + 4(char[]引用) + 24(搞java char[]:头8+length 4+ value 10 + padding 2) = 48

<32位机> 2*N + 40 + padding

Java对象内存的使用情况

https://github.com/Piasy/notes/blob/master/Android-Java/JavaObjectMemoryUsage.md 

空String对象占用内存:

8(header) + 3*4(上述三个int域) + 4(char数组引用) + 12(空char数组header) + 4(char数组padding) = 40字节

9 接口和抽象类的区别

参考:Java抽象类与接口的区别 

http://www.importnew.com/12399.html 

参考:Java 8新特性探究(二)深入解析默认方法 

https://my.oschina.net/benhaile/blog/176007

java8有实现方法了

抽象类(用来捕捉子类的通用特性的):

- 有构造器;

- 不能实例化的类;

- 有public、protected、default修饰符;

- 可以有main方法;

- 单继承;

- 方法可以有默认实现

接口(抽象方法的集合):

- 无构造器;

- 方法只有public修饰符;

- 可以多继承;

- 速度慢;

- 方法无默认实现(JAVA8可以);

- static方法需要实现

场景:

如果基本功能在不断改变,那么就需要使用抽象类。需要多继承,只能使用接口。

理解:抽象类表示这个东西是什么;接口表示这个东西会什么动作。

10 类的静态成员对象存放在哪?

据 JVM 规范,JVM 内存共分为 虚拟机栈、堆、方法区、程序计数器、本地方法栈 五个部分。

Java7 之前,类的静态变量(简称类变量,比如你写的 staff)存放在 永久代(PermGen)—— 在 Hotspot JVM 上,PermGen 就是方法区;Java7 之后,将类变量的存储转移到了 堆。

在方法区有个静态区,静态区专门存放静态变量和静态块。

11 轻量级锁与偏向锁

锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁(但是锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级)。

 引入偏向锁是为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径,因为轻量级锁的获取及释放依赖多次CAS原子指令,而偏向锁只需要在置换ThreadID的时候依赖一次CAS原子指令(由于一旦出现多线程竞争的情况就必须撤销偏向锁,所以偏向锁的撤销操作的性能损耗必须小于节省下来的CAS原子指令的性能消耗)。上面说过,轻量级锁是为了在线程交替执行同步块时提高性能,而偏向锁则是在只有一个线程执行同步块时进一步提高性能。

Java并发编程:Synchronized底层优化(偏向锁、轻量级锁)

http://www.cnblogs.com/paddix/p/5405678.html

12 静态内部类与非静态内部类

http://blog.csdn.net/u012123938/article/details/46684839

相同:

1、 内部类Person只在类 MyMain范围内可见, 若在其它类中初始化, 均是错误的.

2、 静态内部类可以用public、protected、private修饰

不同:

1、 静态内部类中可以定义静态或者非静态的成员,而非静态内部类则不能有静态成员。

2、 静态内部类的非静态成员只能访问外部类的静态变量,而不可访问外部类的非静态变量。而非静态内部类的非静态成员可以访问外部类的非静态变

量。这是由Java语法中"静态方法不能直接访问非静态成员"所限定。

3、 在当前类中,外部成员方法访问静态内部类的非静态成员,可通过实例化静态内部类来访问--->new InnerClass().test(); 。而非静内部类需要说明当前类是哪个--->this.new InnerClass().test();

5、 生成一个静态内部类,它可以不依赖于外部类实例被实例化。而非静态内部类需要在外部类实例化后才能实例化。

静态内部类的对象可以直接生成:MyMain.Person in = new MyMain.Person();----> new + 外部类类名.内部类类名(构造器参数列表),而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类(正常情况下,你不能在接口内部放置任何代码,但嵌套类可以作为接口的一部分,因为它是static 的。只是将嵌套类置于接口的命名空间内,这并不违反接口的规则)

13 String和SringBuilder、StringBuffer的区别

    String 字符串常量

    StringBuffer 字符串变量(线程安全)

    StringBuilder 字符串变量(非线程安全)

    14 Vector和Array和ArrayList的区别

      15 HashMap和HashTable的区别

        参考

        https://www.zhihu.com/question/20581065

        http://blog.csdn.net/zccst/article/details/5056920

        http://www.cnblogs.com/springsource/p/6419462.html   (源码解读)

        HashTable的方法使用synchronized,所以是线程安全的,但是性能差。

        HashMap允许null值键/值

        HashMap在JAVA8中超过8个元素时使用红黑树代替链表,查找复杂度变为O(logN)

        HashTable使用Enumeration,HashMap使用Iterator

        HashTable直接使用对象的hashCode,而HashMap重新计算hash值,而且用与代替求模

        两者都是无序存放

        16 Vector和Array和ArrayList的区别

          17 JAVA面向对象的三大基本特征

          封装:对象要有一个明确的边界

          继承:共性放到父类,特性放到子类

          多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

          18 JAVA多态

          参考:java提高篇(四)-----理解java的三大特性之多态 http://www.cnblogs.com/chenssy/p/3372798.html

          Java多态性理解: http://www.cnblogs.com/jack204/archive/2012/10/29/2745150.html

          多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)

          Java实现多态有三个必要条件:继承、重写、向上转型。

          Java中有两种形式可以实现多态:继承和接口

          19 JAVA重写(Override)和重载(Overload)

          方法重载Overloading:是在一个类中,有多个方法,这些方法的名字相同,但是具有不同的参数列表,和返回值

          方法重写Overriding:是存在于父类与子类之间

          重写方法的规则:

          形参、返回值相同

          访问修饰符范围大于等于被重写方法

          不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常

          参考: http://www.cnblogs.com/fubaizhaizhuren/p/5656230.html

          20 JAVA ThreadLocal

          当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

          ThreadLocal和解决线程安全没有关系,不同线程的变量不共享。

          参考 谈谈ThreadLocal和解决线程安全的关系:

          http://zhangbo-peipei-163-com.iteye.com/blog/2029216

          主流JVM在做完从Java字节码到机器码的编译后,都能做适当的优化来让题主例中的'lo'变量所指向的对象可以被回收。做到这种效果的编译优化技术叫做“活跃分析”(liveness analysis)。

          参考:这段 Java 代码中的局部变量能够被提前回收吗?编译器或 VM 能够实现如下的人工优化吗?

          https://www.zhihu.com/question/34341582/answer/58444959

          找出栈上的指针/引用

          http://rednaxelafx.iteye.com/blog/1044951

          21 轻量级锁和偏向锁

          没太看懂!@TODO

          http://blog.csdn.net/wolegequdidiao/article/details/45116141

          - 轻量级锁:在无竞争的情况下使用CAS操作去消除同步使用的互斥量

          - 偏向锁:在无竞争的情况下把整个同步都消除掉,连CAS操作都不做了

          22 java线程sleep join yield wait notify notifyAll

          java线程sleep join yield wait notify notifyAll

          http://www.jianshu.com/p/c9f847101fae

          1.sleep()

          使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁

          2.join()

          等待调用该方法的线程执行完毕后再往下继续执行。

          3.yield()

          它与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会

          4.wait()和notify()、notifyAll()

          这三个方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用这三个方法。

          5.run()和start()

          这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用 run() 方法

          线程有四种状态:

          产生(New):线程对象已经产生,但尚未被启动,所以无法执行。

          可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。

          死亡(Dead):当一个线程正常结束,它便处于死亡状态。

           停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。

          23 JAVA 匿名内部类

          在使用匿名内部类的过程中,我们需要注意如下几点:

            1、使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。

            2、匿名内部类中是不能定义构造函数的。

            3、匿名内部类中不能存在任何的静态成员变量和静态方法。

            4、匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。

            5、匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

          当所在的方法的形参需要被内部类里面使用时,该形参必须为final

          拷贝引用,为了避免引用值发生改变,例如被外部类的方法修改等,而导致内部类得到的值不一致,于是用final来让该引用不可改变。

          java提高篇(九)-----详解匿名内部类

          http://blog.csdn.net/chenssy/article/details/13170015

          静态内部类和非静态内部类的区别

          http://blog.csdn.net/u012123938/article/details/46684839

          <span style="background-color: rgb(255, 255, 255); color: rgb(77, 77, 77);"--<---------------------<span style="background-color: rgb(255, 255, 255); color: rgb(77, 77, 77);"--<---------------------<span style="background-color: rgb(255, 255, 255); color: rgb(77, 77, 77);"--<---------------------<span style="background-color: rgb(255, 255, 255); color: rgb(77, 77, 77);"--<---------------------

          JAVA基础知识整理

          类、接口、数据类型等

          1 JAVA关键字

          权限

          public default protected private

          指代

          this super

          类相关

          class interface package enum

          对象相关

          new instanceof implements extends import

          修饰

          static final abstract native strictfp transient volatile synchronized

          断言

          assert

          基础数据类型

          boolean int byte char long float double short void null true false

          流程控制

          break if for continue else switch case while do return

          异常

          try catch finally throws throw 

          保留关键字

          const goto

          2 数据类型

          2.1 分类

          基本数据类型

                     |-------> 数值型

                     |                   |-----> 整数类型 byte short int long

                     |                   |-----> 浮点类型 float double

                     |-------> 字符型 char

                     |-------> 布尔型 boolean

          引用数据类型

                     |-------> 类 class

                     |-------> 接口 interface

                     |-------> 数组 [ ]

          2.2 占用空间

          2.2.1 基本数据类型

          byte                8-bit

          short               16-bit

          int                   32-bit

          long                64-bit

          float               32-bit

          double            64-bit

          boolean          大小没有精确定义,1bit会对其到8bit

          Primitive Data Types

          https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

          2.2.2 引用数据类型

          - Object类实例:8字节

          - Object类实例数组:12字节,比Object类实例多了个length域;

          - 一维数组,数据区域,length * sizeof(element),此外,对于object是保存的引用,为4字节

          - 二维数组,每一行都是一个数组,故每一行都有object的开销

          - String对象包含:char数组,offset,length,hashcode这四部分内容

          - 为了便于寻址,对象内存会8字节对齐;

          - 空String对象占用内存:8(header) + 3*4(上述三个int域) + 4(char数组引用) + 12(空char数组header) + 4(char数组padding) = 40字节

          Java对象内存的使用情况

          https://github.com/Piasy/notes/blob/master/Android-Java/JavaObjectMemoryUsage.md

          3 面向对象

          3.1 三大特征

          面向对象的特征:

          - 封装(encapsulation)     是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

          - 继承(inheritance)          继承就是子类继承父类的特征和行为

          - 多态(polymorphism)     同一个行为具有多个不同表现形式或形态的能力

          3.2 封装

          好处:将变化隔离,便于使用。提高重用性、安全性。

          类:描述事物的属性和行为 (构造函数 、成员变量、函数)

          权限修饰符: public default protected private

          3.3 继承

          好处:提高了代码的复用性。让类与类之间产生了关系,提供了多态的前提。

          3.3.1 抽象类

          抽象类是用来捕捉子类的通用特性的 。

          抽象方法:被abstract修饰的方法是抽象方法,抽象方法没有方法体。

          3.3.2 接口

          接口是抽象方法的集合。

          3.3.3 内部类

          内部类分为以下四种:

          - inner class(内部类)

          - 局部内部类

          - 匿名内部类

          - 静态嵌套类

          inner class:一个内部类被声明在另外一个类当中

          - 内部类的实例只能通过外部类的实例来创建。

          OuterClass.MyInnerClass inner = new OuterClass().new MyInnerClass();

          局部内部类:局部内部类被定义在外部类的方法当中

          - 如果你想使用内部类,必须同一方法中实例化内部类

          - 只有 abstract 和 final 这两个修饰符被允许修饰局部内部类

          - 只有在方法的局部变量被标记为 final 或 局部变量是 effectively final的, 内部类才能使用它们。

          MyInnerClassDemo inner = new MyInnerClassDemo();

          匿名内部类:没有名字

          - 只能被实例化一次

          - 通常被声明在方法或代码块的内部,以一个带有分号的花括号结尾

          - 因为没有名字,所以没有构造函数

          - 不能是静态的(static)

          Animal d = new Animal(){

                    void play(){

                          System.out.println("play with human");

                    }

            };

          静态嵌套类:一个静态嵌套类是被标记为 static 的内部类

          - 静态嵌套类无法访问外部类的非静态成员。

          Outer.Nested n= new Outer.Nested();

          3.4 多态

          好处:多态的存在提高了程序的扩展性和后期可维护性

          多态的实现方式:基于继承、基于接口

          多态的表现方式:方法重载(重载)、成员覆盖(重写)

          重写(Override)是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。

          重载(Overload)是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

          Java实现多态有三个必要条件(前提):继承、重写、向上转型。

          4 IO

          了解 文件:InputStream Reader Channel 网络:Socket SocketChannel Selector

          ------------------------------------

          设计模式

          笔记 Android 知识点 里有部分记录

          23种设计模式的优点与缺点概况

          http://www.cnblogs.com/WoodJim/p/4715385.html 

          Java开发中的23种设计模式详解

          http://zz563143188.iteye.com/blog/1847029 

          可参考,但是里面有很多错误

          设计模式

          https://gof.quanke.name/

          《设计模式之禅》

          0 设计模式

          0.1 分类

          总体来说设计模式分为三大类:

          创建型模式,共六种:简单工厂模式、工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

          结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

          行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

          0.2 原则

          (1)单一职责原则     Single Responsibility Principle, SRP

          定义:一个类只负责一个功能领域中的相应职责,即一个类只有一个引起它变化的原因

          作用:它用于控制类的粒度大小

          (2)开闭原则          Open-Closed Principle, OCP

          定义:软件实体应尽量在不修改原有代码的情况下进行扩展

          作用:使得软件系统在拥有适应性和灵活性的同时具备较好的稳定性和延续性

          (3)里氏代换原则     Liskov Substitution Principle, LSP

          定义:所有引用基类(父类)的地方必须能透明地使用(替换无影响) 其子类的对象。

          作用:里氏代换原则是实现开闭原则的重要方式之一

          在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象

          (4)依赖倒转原则     Dependency Inversion Principle, DIP

          定义:不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程

          作用:在引入抽象层后,系统将具有很好的灵活性,在程序中尽量使用抽象层进行编程,而将具体类写在配置文件中

          在实现依赖倒转原则时,我们需要针对抽象层编程,而将具体类的对象通过依赖注入(DependencyInjection, DI)的方式注入到其他对象中,常用的注入方式有三种,分别是:构造注入,设值注入(Setter注入)和接口注入。

          (5)接口隔离原则     Interface Segregation Principle, ISP

          定义:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口(指一个类型所具有的方法特征的集合或者特定语言的接口)

          作用:一方面接口承担了太多职责,一方面导致该接口的实现类很庞大,灵活性较差。另一方面由于客户端针对大接口编程,将在一定程序上破坏程序的封装性,客户端看到了不应该看到的方法

          (6)合成复用原则     Composition/Aggregate Reuse Principle, CARP

          定义:尽量使用对象组合,而不是继承来达到复用的目的

          作用:组合/聚合可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少;其次才考虑继承,在使用继承时,需要严格遵循里氏代换原则,有效使用继承会有助于对问题的理解,降低复杂度,而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度,因此需要慎重使用继承复用。

          (7)迪米特法则     (Law of Demeter, LoD

          定义:一个软件实体应当尽可能少地与其他实体发生相互作用。

          作用:就是通过引入一个合理的第三者来降低现有对象之间的耦合度

          1 工厂方法模式(Factory Method)

          1.1 简单工厂模式     Simple Factory Pattern

          传入一个正确的参数,就可以获取你所需要的对象

          角色:

          Factory(工厂角色)

          Product(抽象产品角色)

          ConcreteProduct(具体产品角色)

          1.2工厂方法模式     Factory Method Pattern

          工厂方法模式又简称为工厂模式(Factory Pattern),又可称作虚拟构造器模式(Virtual Constructor Pattern)或多态工厂模式(Polymorphic Factory Pattern)。

          定义一个用于创建对象的接口,让子类决定将哪一个类实例化

          减少具体产品与工厂类之间的耦合度

          角色:

          Product(抽象产品)

          ConcreteProduct(具体产品)

          Factory(抽象工厂)

          ConcreteFactory(具体工厂)

          1.3 抽象工厂模式     Abstract Factory Pattern

          提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

          角色:

          AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。

          ConcreteFactory(具体工厂)

          AbstractProduct(抽象产品)

          ConcreteProduct(具体产品)

          2 单例模式 Singleton Pattern

          定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

          2.1 饿汉式单例类

          在定义静态变量的时候实例化单例类

          饿汉式单例类在类被加载时就将自己实例化,它的优点在于无须考虑多线程访问问题,可以确保实例的唯一性;从调用速度和反应时间角度来讲,由于单例对象一开始就得以创建,因此要优于懒汉式单例。

          2.2 懒汉式单例类

          在第一次调用getInstance()方法时实例化

          为了解决线程安全问题,在synchronized方法块里加入第二重判断。称为双重检查锁定(Double-Check Locking)

          需要注意的是,如果使用双重检查锁定来实现懒汉式单例类,需要在静态成员变量instance之前增加修饰符volatile,被volatile修饰的成员变量可以确保多个线程都能够正确处理,且该代码只能在JDK 1.5及以上版本中才能正确执行。由于volatile关键字会屏蔽Java虚拟机所做的一些代码优化,可能会导致系统运行效率降低,因此即使使用双重检查锁定来实现单例模式也不是一种完美的实现方式。

          需要通过双重检查锁定等机制进行控制,这将导致系统性能受到一定影响。

          3 代理模式     Proxy Pattern

          给某一个对象提供一个代理或占位符,并由代理对象来控制对原对象的访问。

          角色:

          Subject(抽象主题角色)               它声明了真实主题和代理主题的共同接口

          Proxy(代理主题角色)                    它包含了对真实主题的引用

          RealSubject(真实主题角色)          它定义了代理角色所代表的真实对象

          4 装饰者模式     Decorator Pattern

          动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。装饰模式是一种对象结构型模式。

          角色:

          Component(抽象构件)                         它是具体构件和抽象装饰类的共同父类

          ConcreteComponent(具体构件)          它是抽象构件类的子类

          Decorator(抽象装饰类)                         它也是抽象构件类的子类,用于给具体构件增加职责

          ConcreteDecorator(具体装饰类)               它是抽象装饰类的子类,负责向构件添加新的职责

          由于具体构件类和装饰类都实现了相同的抽象构件接口,因此装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。

          为了让系统具有更好的灵活性和可扩展性,克服继承复用所带来的问题

          5 观察者模式     Observer Pattern

          定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。

          观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

          角色:

          Subject(目标)                                        attach() detach() notify()

          ConcreteSubject(具体目标)

          Observer(观察者)                                   update()

          ConcreteObserver(具体观察者)

          目标又称为主题,它是指被观察的对象。它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()

          具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。

          观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。

          在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的update()方法。通常在实现时,可以调用具体目标类的attach()方法将自己添加到目标类的集合中或通过detach()方法将自己从目标类的集合中删除。

发表评论

邮箱地址不会被公开。 必填项已用*标注