1.System类不简单
1 | public class LearnSystem { |
System.currentTimeMillis()
返回当前的计算机时间,时间的表达格式为当前计算机时间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。
1 | public static long currentTimeMillis() // 返回long |
2.String类的好兄弟:StringBuilder
它是一个非常方便用于拼接和处理字符串的类,它和String不同在于它是可变的。
这对“好兄弟”的关系有点像C++中的string类和vector。
StringBuffer 与StringBuilder类似。
由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
String、StringBuffer、StringBuilder三者的对比
String
:不可变的字符序列;底层使用char[]存储StringBuffer
:可变的字符序列;线程安全的,效率低;底层使用char[]存储StringBuilder
:可变的字符序列;jdk5.0新增的,线程不安全的,效率高;底层使用char[]存储
虽然可以直接拼接String字符串,但是,在循环中,每次循环都会创建新的字符串对象,然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。
为了能高效拼接字符串,Java标准库提供了StringBuilder
,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder
中新增字符时,不会创建新的临时对象:
1 | public static void main(String[] args) { |
1 | //常用方法 |
append、reverse、delete和insert均不会创建新对象,直接在原对象上修改。
3.多态里更多的语法
静态多态:重载(Overload)
1 | //重载调用哪个方法,和参数的引用类型相关,和引用实际指向的类型无关 |
重载总结:静态多态,调用的方法和参数实际指向的对象无关,只和引用本身的类型相关。
因为调用时参数类型是确定的,所以,在编译期间就可以明确的知道哪个方法会被调用。如果有多种可能,则会有编译错误
如果没有类型完全匹配的候选,则根据类型的继承关系向下撸着找。找到最贴近参数类型的那个方法
无论是静态方法,还是成员方法,重载寻找方法的顺序是一样的,在这里就不赘述了
动态多态:覆盖(Override)
4.继承专属的访问控制符
protected 可见性= default + 对子类可见
子类覆盖父类的方法,不可以使用可见性更低的修饰符,但可以使用可见性更高的修饰符。
5.final修饰符
final意为最终的。不可变!!不需要再扩充功能了,已经够用了。
我们常用的String类就是用final修饰的,不能被随意修改。
final修饰变量,也就成了常量,必须在定义时初始化,或在构造器里初始化,且不能修改。
final修饰static变量,必须在定义时初始化,或在static{}
代码块里赋值。
final修饰父类的方法,确保不会被子类覆盖。
final不能修饰构造方法!
final修饰的类不可被继承:比如:String类、System类、StringBuffer类。
final修饰引用:不能修改令引用指向别的对象,但是可以修改引用指向的对象。
这就有C语言的常量指针内味了,不可修改指针的指向,但能修改指针指向的值。
注:常量指针与指向常量的指针不一样!
6.继承里的静态方法
静态方法可以被继承,方法签名和返回值必须一样。
用引用调用(即用对象)静态方法不会被覆盖,不推荐这样调用,应该用类名调用。
1 | m.staticMethod(); |
7.for-each循环
语法基本同C++/Python中的类似写法,循环对象必须是一个数组或者一个实现了Iterable接口的类对象。
1 | int[] arr= {1,2,3,4,5} |