Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
scu-zzy committed Aug 1, 2020
1 parent e0a4c50 commit 6eed4e5
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 6 deletions.
9 changes: 9 additions & 0 deletions JVM.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,15 @@ Java 虚拟机使用该算法来判断对象是否可被回收,GC Roots 一般
- 方法区中类静态属性引用的对象
- 方法区中的常量引用的对象

一个对象可以属于多个root,GC Roots有以下几种:
- Class 由系统类加载器(system class loader)加载的对象,这些类是不能够被回收的,他们可以以静态字段的方式保存持有其它对象。我们需要注意的一点就是,通过用户自定义的类加载器加载的类,除非相应的Java.lang.Class实例以其它的某种(或多种)方式成为roots,否则它们并不是roots.
- Thread 活着的线程
- Stack Local Java方法的local变量或参数
- JNI Local JNI方法的local变量或参数
- JNI Global 全局JNI引用
- Monitor Used 用于同步的监控对象
- Held by JVM 用于JVM特殊目的由GC保留的对象,但实际上这个与JVM的实现是有关的。可能已知的一些类型是:系统类加载器、一些JVM知道的重要的异常类、一些用于处理异常的预分配对象以及一些自定义的类加载器等。然而,JVM并没有为这些对象提供其它的信息,因此需要去确定哪些是属于"JVM持有"的了。

### 3. 方法区的回收 ###

因为方法区主要存放永久代对象,而永久代对象的回收率比新生代低很多,所以在方法区上进行回收性价比不高。
Expand Down
18 changes: 18 additions & 0 deletions Java基础.md
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,24 @@ String 不可变性天生具备线程安全,可以在多个线程中安全地

3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便。

4. 如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。 从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了"多重继承"。

## 内部类的好处 ##

### 静态内部类的作用: ###

1 只是为了降低包的深度,方便类的使用,静态内部类适用于包含类当中,但又不依赖与外在的类。

2 由于Java规定静态内部类不能用使用外在类的非静态属性和方法,所以只是为了方便管理类结构而定义。于是我们在创建静态内部类的时候,不需要外部类对象的引用。

### 非静态内部类的作用: ###

1 内部类继承自某个类或实现某个接口,内部类的代码操作创建其他外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。

2 使用内部类最吸引人的原因是:每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响

3 如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。 从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了"多重继承"。

## 内部类的共性 ##

1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号 。
Expand Down
20 changes: 14 additions & 6 deletions 设计模式/结构型模式.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,25 @@

## 代理

用一个代理来隐藏具体实现类的实现细节,通常还用于在真实的实现的前后添加一部分逻辑。

既然说是代理,那就要对客户端隐藏真实实现,由代理来负责客户端的所有请求。当然,代理只是个代理,它不会完成实际的业务逻辑,而是一层皮而已,但是对于客户端来说,它必须表现得就是客户端需要的真实实现。

![](https://camo.githubusercontent.com/aa773bc148092510f7bee949498cccdc6e082b85/68747470733a2f2f6a617661646f6f702e636f6d2f626c6f67696d616765732f64657369676e2d7061747465726e2f70726f78792d312e706e67)
代理类与委托类实现同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。具体方法由委托类实现,在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。

Java中代理的实现一般分为三种:JDK静态代理、JDK动态代理以及CGLIB动态代理。

**JDK静态代理**:创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。

**JDK动态代理**:JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反射机制在运行时创建代理类的。
优势:

在不修改目标对象的前提下,可以通过代理类对被代理类功能扩展。



**JDK动态代理**:JDK静态代理是通过直接编码创建的,而JDK动态代理是利用反射机制在运行时创建代理类及其对象。

动态代理相对于静态代理的优势:

就静态代理而言,在委托类特别多的应用场景,就要相应的添加许多的代理类,这显然增加了应用程序的复杂度,而使用动态代理就可以减少代理类的数量,相对降低了应用程序的复杂度。

假如你想干三件事(相当于三段代码),安排好以后如果你想调换顺序,换做以前,你必须去代码里进行改动,改动代码就意味着你要重新测试。而如果你用动态代理就不会,他把每件事看作一个方面,每个方面是“织入”的,改变顺序不影响整体。

**CGLIB**:JDK代理要求被代理的类必须实现接口,有很强的局限性。而CGLIB动态代理则没有此类强制性要求。简单的说,CGLIB会让生成的代理类继承被代理类,并在代理类中对代理方法进行强化处理(前置处理、后置处理等)。

Expand Down

0 comments on commit 6eed4e5

Please sign in to comment.