0%

实质

ArrayList的底层实现就是数组

其动态变化的长度是由其扩容机制所组成的,在jdk1.8中,扩容代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}

可以看出,新的容量是原来的1.5倍.

1
2
3
4
/**
* Default initial capacity.
*/
private static final int DEFAULT_CAPACITY = 10;

默认长度是10

饿汉模式-序列化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package tech.xixing.design.pattern.creational.singleton;

import java.io.Serializable;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 10:38
*/
public class HungrySingleton implements Serializable {
//private final static HungrySingleton hungrySingleton=new HungrySingleton();

private final static HungrySingleton hungrySingleton;
static {
hungrySingleton=new HungrySingleton();
}
private HungrySingleton(){

}

public static HungrySingleton getInstance(){
return hungrySingleton;
}

private Object readResolve(){
return hungrySingleton;
}


}

在最后加入方法readResolve()即可在反序列化中返回原来对象。

反射攻击预防

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package tech.xixing.design.pattern.creational.singleton;

import java.io.Serializable;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 10:38
*/
public class HungrySingleton implements Serializable {
//private final static HungrySingleton hungrySingleton=new HungrySingleton();

private final static HungrySingleton hungrySingleton;
static {
hungrySingleton=new HungrySingleton();
}
//反射攻击预防
private HungrySingleton(){
if(hungrySingleton!=null){
throw new RuntimeException("单例模式禁止反射");
}

}

public static HungrySingleton getInstance(){
return hungrySingleton;
}

private Object readResolve(){
return hungrySingleton;
}


}

懒汉模式

对于懒汉模式,并不能对反射攻击进行有效防御

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package tech.xixing.design.pattern.creational.singleton;

/**
* @author xixing
* @version 1.0
* @date 2020/6/1 8:45
*/
public class LazySingleton {
private static LazySingleton lazySingleton=null;

private static boolean flag=true;

private LazySingleton(){
if(!flag){
throw new RuntimeException("单例模式禁止反射");
}else {
flag=false;
}

}

/**
* 如果锁的是静态方法,相当于把这个class给锁了
* 锁的不是静态方法,相当于把堆内存中的实例锁了
* @return
*/
public synchronized static LazySingleton getInstance(){
if(lazySingleton==null){
lazySingleton=new LazySingleton();
}
return lazySingleton;
// synchronized (LazySingleton.class){
// if(lazySingleton==null){
// lazySingleton=new LazySingleton();
// }
// }
// return lazySingleton;
}


}
1
2
3
4
5
6
7
8
9
10
11
12
Class objectClass=LazySingleton.class;
LazySingleton lazySingleton = LazySingleton.getInstance();
Field flag=lazySingleton.getClass().getDeclaredField("flag");
flag.setAccessible(true);
flag.set(lazySingleton,true);
Constructor constructor=objectClass.getDeclaredConstructor();
constructor.setAccessible(true);
LazySingleton lazySingleton1 = (LazySingleton) constructor.newInstance();
//HungrySingleton hungrySingleton =(HungrySingleton) constructor.newInstance();
//HungrySingleton hungrySingleton1=HungrySingleton.getInstance();
System.out.println(lazySingleton);
System.out.println(lazySingleton1);

ctrl+alt+b是查看接口的实现类

ctrl+f12是查该类的方法

ctrl+n是查整个项目的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package site.xixing.io;

import java.io.File;

/**
* @author xixing
* @version 1.0
* @date 2020/5/31 8:03
*/
public class ReadDirectory {

public static void main(String[] args) {
File file=new File("D:\\wx");
File[] files = file.listFiles();
for (File file1 : files) {
String substring = file1.getName().substring(2);
String newFilePath=file1.getParent()+File.separator+substring;
File newFile=new File(newFilePath);
file1.renameTo(newFile);

}
}
}

类图

image-20200530154107595

1
2
3
4
5
6
7
+为 public
-为private
#为protect
~为default
加下划线为static
斜体为abstract
所以整个类应该斜体

image-20200530154219951