Java学习
Java基础的学习很重要
Java学习
一、面向对象
1.面向对象五大原则
1.单一自责原则(Single-Responsibility Principle)
- 一个类,最好只做一件事,只有一个引起它的变化
2.开放封闭原则(Open-Close principle)
- 软件实体应该是可扩展的,而不可修改的。也就是,对扩展开放,对修改封闭的。
3.里氏替换原则(Liskov-Substitution Principle)
- 子类必须能够替换其基类。这一思想体现为对继承机制的约束规范,只有子类能够替换基类时,才能保证系统在运行期内识别子类,这是保证继承复用的基础。
4.依赖倒置原则(Dependency-Inversion Principle)
- 依赖于抽象。具体而言就是高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。
5.接口隔离原则(Interface-Segregation Principle)
- 使用多个小的专门的接口,而不要使用一个大的总接口。
2. 多用组合,少用继承
建议在同样可行的情况下,优先使用组合而不是继承。
因为组合更安全,更简单,更灵活,更高效。
3.类变量,成员变量,局部变量
类变量:存储在方法区中。private static int a;
成员变量:存储在堆内存中
局部变量:存储在栈内存中
- 抽象类与接口的区别
- 类关系示例图
- POJO的分类
4.成员变量的方法作用域
- public:表明该成员变量或者方法是对所有类或者对象都是可见的,所有类或者对象都可以直接访问
- private:表明该成员变量或者方法是私有的,只有当前类对其具有访问权限,除此之外其他类或者对象都没有访问权限.子类也没有访问权限.
- protected:表明成员变量或者方法对类自身,与同在一个包中的其他类可见,其他包下的类不可访问,除非是他的子类
- default:表明该成员变量或者方法只有自己和其位于同一个包的内可见,其他包内的类不能访问,即便是它的子类
5.基本类型
- 不能用浮点型表示金额
- 由于计算机中保存的小数其实是十进制的小数的近似值,并不是准确值,所以,千万不要在代码中使用浮点数来表示金额等重要的指标
- 建议使用BIgDecimal或者Long来表示金额
5.1自动拆装箱
1 | //java代码 |
- 此时如果i值为null,就会发生NPE(空指针异常)。
1 | Integer test1 = 3; |
其中的 Javadoc 详细的说明了缓存支持 -128 到 127 之间的自动装箱过程。最大值 127 可以通过
-XX:AutoBoxCacheMax=size
修改。实际上这个功能在 Java 5 中引入的时候,范围是固定的 -128 至 +127。后来在 Java 6 中,可以通过
java.lang.Integer.IntegerCache.high
设置最大值。在 Boxing Conversion 部分的 Java 语言规范(JLS)规定如下:
如果一个变量 p 的值是:
- -128 至 127 之间的整数 (§3.10.1)
- true 和 false 的布尔值 (§3.10.3)
\u0000
至\u007f
之间的字符 (§3.10.4)
注意:如果一个 for 循环中有大量拆装箱操作,会浪费很多资源。
6.字符串的不可变性String
String类的所有方法都没有改变字符串本身的值,都是返回了一个新的对象。
- 如果我们想要一个可修改的字符串,可以选择StringBuffer 或者 StringBuilder这两个代替String。
如有可能,我愿意任何时候都使用不可变对象。 I would use an immutable whenever I can.
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
42
43
44
+ 缓存-字符串对象使用频率高,将其缓存起来,相同的指向一个地址空间,节省资源
+ 安全性-字符串存储敏感数据,不可变,可以让开发者足够信任它
+ 线程安全-多个线程访问它们时,它们不会被改变。
+ hashcode缓存-由于字符串对象被广泛地用作数据结构,它们也被广泛地用于哈希实现,如HashMap、HashTable、HashSet等。在对这些散列实现进行操作时,经常调用hashCode()方法。
+ 性能-因为字符串不可变,所以可以用字符串池缓存,可以大大节省堆内存。而且还可以提前对hashcode进行缓存,更加高效
### 7.String类中常见用法
> 内存泄露:在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。 内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费。
#### 1.JDK6与JDK7中substring的原理及区别
Jdk6:substring指向原string字符串其中的一部分数据
Jdk7:重新创建对象
#### 2.replaceFirst、replaceAll、replace区别
replace(CharSequence target, CharSequence replacement) ,用replacement替换所有的target,两个参数都是字符串。
replaceAll(String regex, String replacement) ,用replacement替换所有的regex匹配项,regex很明显是个正则表达式,replacement是字符串。
replaceFirst(String regex, String replacement) ,基本和replaceAll相同,区别是只替换第一个匹配项。
```java
String string = "abc123adb23456aa";
System.out.println(string);//abc123adb23456aa
//使用replace将a替换成H
System.out.println(string.replace("a","H"));//Hbc123Hdb23456HH
//使用replaceFirst将第一个a替换成H
System.out.println(string.replaceFirst("a","H"));//Hbc123adb23456aa
//使用replace将a替换成H
System.out.println(string.replaceAll("a","H"));//Hbc123Hdb23456HH
//使用replaceFirst将第一个数字替换成H
System.out.println(string.replaceFirst("\\d","H"));//abcH23adb23456aa
//使用replaceAll将所有数字替换成H
System.out.println(string.replaceAll("\\d","H"));//abcHHHadbHHHHHaa
3.string中的“+”
代码:
1 | String hello = "Hello" |
反编译后:
1 | String wechat = "Hollis"; |
通过StringBuilder.append实现的拼接
4.字符串拼接的几种方法和区别
StringBuffer是线程安全的
StringUtils.join的源码,其实也是通过StringBuilder实现的
1 | public static String join(final Object[] array, String separator, final int startIndex, final int endIndex) { |
效率对比
1 | long t1 = System.currentTimeMillis(); |
测试结果:StringBuilder<
StringBuffer<
concat<
+<
StringUtils.join
1 | + cost:5119 |
Collection和Collections区别
Collection是一个集合接口.它提供了对集合对象进行基本操作的通用接口方法.是list,set等等父接口
Collections是一个包装类.她包含有各种关于集合操作的静态多态方法.类无法实例化,像工具类,服务与Java的Colloection框架.
Set和List区别
List,Set都是继承自Collection接口。都是用来存储一组相同类型的元素的。
List特点:元素有放入顺序,元素可重复
先放入的元素排在前面
Set特点:元素无放入顺序,元素不可重复.
无顺序,即先放入的元素不一定排在前面。 不可重复,即相同元素在set中只会保留一份。所以,有些场景下,set可以用来去重。 不过需要注意的是,set在元素插入时是要有一定的方法来判断元素是否重复的。这个方法很重要,决定了set中可以保存哪些元素。
ArrayList和LinkedList和Vector的区别
三者都实现了List接口,区别在于实现方式不同,对不同的操作具有不同的效率.
ArrayList是一个可改变大小的数组,其大小会顺随着元素的加入而动态地增长.内部通过get,set方法进行访问.本质上是个数组.