1. JAVA 中的堆、 栈 和 常量池 :
1)寄存器
最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制。
2)栈
存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中)。存储的都是局部变量,而且变量所属的作用域一旦结束,该变量就自动释放。
3)堆
存放所有new出来的对象和成员变量。成员变量存储在堆中的对象里面。
4) 静态域
存放静态成员(static定义的)
5)常量池
存放字符串常量和基本类型常量(public static final)。
6)非RAM存储
硬盘等永久存储空间
2. 逻辑运算符:| || & &&
&&和& 都是与运算符:&&和&的运算结果是一样的,但是运算过程有点小区别,&无论左边的运算结果是什么,右边都参与运算;&&当左边为false时,右边不参与运算。
|和||
都是或运算符:|和||的运算结果是一样的,但是运算过程有点小区别,|无论左边的运算结果是什么,右边都参与运算;||当左边为true时,右边不参与运算。
3. i++与++i
int a=3,b;
a++ => a=4
++a => a=4
b=a++ => a=4,b=3
b=++a => a=4,b=4
4. 数组定义方法
(1)一维数组
需要一个容器,不明确容器的具体数据:int[] arr = new int[3];
需要一个容器,存储已知的具体数据: int[] arr =new int[]{12,34,48,96}; int[] arr ={12,34,48,96};
(2)二位数组
int[][] arr=new int[3][2];
或者
int[][] arr=new int[3][];
arr[0]=new int[3];
arr[1]=new int[1];
arr[2]=new int[2];
或者
int[][] arr={{0,1,2},{3,4,5},{6,7,8}};
5.函数的重载。
1)同一个类,
2)同名。
3)参数个数不同。or 参数类型不同。
4)函数重载和返回值类型无关。
5)java是严谨性语言,如果函数出现的调用的不确定性,会编译失败。
6. java的构造函数的特点
1)函数名与类名相同
2)没有返回值,void也不行
3)可以重载,默认提供无参构造函数,如果写了带参构造函数,则不再提供无参构造函数。
4)主要用来在创建对象时初始化对象,在创建对象时被自动调用。总与new一起使用。
7. java的4种访问权限
包与包之间的类进行访问,被访问的类必须是public的,被访问的包中的类的方法也必须是public的。 public protected default private
同一类中 ok ok ok
同一包中 ok ok ok
子类中 ok ok
不同包中 ok
8. 静态static什么时候用?
1)静态变量
当分析对象中所具备的成员变量的值都是相同的,这时这个成员就可以被静态修饰。
只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。
如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的。
2)静态函数
函数是否用静态修饰,就参考一点,就是该函数功能是否有访问到对象中的特有数据。
简单点从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。
如果不需要,就可以将该功能定义成静态的。当然也可以定义成非静态的,但是非静态的需要被对象调用,而仅创建对象调用非静态,没有访问特有数据的方法,该对象的创建是没有意义的。
9.继承
java中支持单继承。不直接支持多继承,但对C++中的多继承机制进行改良。
单继承:一个子类只能有一个直接父类。
多继承:一个子类可以有多个直接父类(。 不直接支持,因为多个父类中有相同成员,会产生调用不确定性。在java中是通过"多实现"的方式来体现。
10.覆盖
当子父类中出现成员函数一模一样的情况,会运行子类的函数。这种现象,称为覆盖操作。这是函数在子父类中的特性。函数两个特性:
1)重载。同一个类中。overload
2)覆盖。子类中。覆盖也称为重写,覆写。override
覆盖注意事项:
1,子类方法覆盖父类方法时,子类权限必须要大于等于父类的权限。
2,静态只能覆盖静态,或被静态覆盖。
11.抽象类
1)特点:
a.方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。
抽象方法必须定义在抽象类中。该类必须也被abstract修饰。
b.抽象类不可以被实例化。为什么?因为调用抽象方法没意义。
c.抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化。否则,这个子类还是抽象类。
2)抽象类中有构造函数吗?有,用于给子类对象进行初始化。
3)抽象类可以不定义抽象方法吗?
可以的。 但是很少见,目的就是不让该类创建对象。AWT的适配器对象就是这种类。
通常这个类中的方法有方法体,但是却没有内容。
12.final关键字:
1) final是一个修饰符,可以修饰类,方法,变量。
2) final修饰的类不可以被继承。
3) final修饰的方法不可以被覆盖。
4) final修饰的变量是一个常量,只能赋值一次。
为什么要用final修饰变量。其实在程序如果一个数据是固定的,
那么直接使用这个数据就可以了,但是这样阅读性差,所以它该数据起个名称。
而且这个变量名称的值不能变化,所以加上final固定。
5) 写法规范:常量所有字母都大写,多个单词,中间用_连接。
13.抽象类和接口的异同点:
相同点:
都是不断向上抽取而来的。
不同点:
1)抽象类需要被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2)抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
接口中只能定义抽象方法,必须由子类去实现。
3)抽象类的继承,是is a关系,在定义该体系的基本共性内容。
接口的实现是 like a 关系,在定义体系额外功能。
14.多态
猫这类事物即具备者猫的形态,又具备着动物的形态,这就是对象的多态性。
简单说:就是一个对象对应着不同类型.
多态在代码中的体现:
父类或者接口的引用指向其子类的对象。
多态的好处:提高了代码的扩展性,前期定义的代码可以使用后期的内容。
多态的弊端:前期定义的内容不能使用(调用)后期子类的特有内容。
多态的前提:
1,必须有关系,继承,实现。
2,要有覆盖。
多态时成员的特点:
1)成员变量。
编译时:参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败。
运行时:参考引用型变量所属的类中的是否有调用的成员变量,并运行该所属类中的成员变量。
简单说:编译和运行都参考等号的左边。
2)成员函数(非静态)。
编译时:参考引用型变量所属的类中的是否有调用的函数。有,编译通过,没有,编译失败。
运行时:参考的是对象所属的类中是否有调用的函数。
简单说:编译看左边,运行看右边。
因为成员函数存在覆盖特性。
3)静态函数。
编译时:参考引用型变量所属的类中的是否有调用的静态方法。
运行时:参考引用型变量所属的类中的是否有调用的静态方法。
简单说,编译和运行都看左边。
其实对于静态方法,是不需要对象的。直接用类名调用即可。
15. 异常捕捉
如果不能处理则使用throws抛出,如果可以处理则使用try catch进行处理
异常处理的捕捉形式,这是可以对异常进行针对性处理的方式
具体格式:
try
{
// 需要被检测异常的代码
}
catch(异常类 变量) // 该变量用于接受发生异常的对象
{
//真正处理该异常的代码
}
finally //通常关于关闭(释放)资源
{
// 一定会被执行的代码
}
异常处理的原则:
1) 函数内容如果抛出需要检测的异常,那么函数上必须要声明,负责必须在函数内用try catch捕捉,否则编译失败
2)如果调用到了声明异常的函数,要么try catch 要么throws,否则编译失败。
3)什么时候catch 什么时候throws呢?
功能内容可以解决,用catch。解决不了,用throws告诉调用者,由调用者解决。
4)一个功能如果跑出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理。内部有几个需要检测的异常,就抛几个异常,跑出几个,就catch几个。
16.如何创建一个线程呢?
1)创建线程方式一:继承Thread类。
步骤:
a.定义一个类继承Thread类。
b.覆盖Thread类中的run方法。
c.直接创建Thread的子类对象创建线程。
d.调用start方法开启线程并调用线程的任务run方法执行。
可以通过Thread的getName获取线程的名称 Thread-编号(从0开始),主线程的名字就是main。
2)创建线程的第二种方式:实现Runnable接口。
a.定义类实现Runnable接口。
b.覆盖接口中的run方法,将线程的任务代码封装到run方法中。
c.通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。
为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。所以要在线程对象创建时就必须明确要运行的任务。
d.调用线程对象的start方法开启线程。
3)实现Runnable接口的好处:
a.将线程的任务从线程的子类中分离出来,进行了单独的封装。按照面向对象的思想将任务的封装成对象。
b.避免了java单继承的局限性。
所以,创建线程的第二种方式较为常用。
17.等待/唤醒机制。
涉及的方法:
1)wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。
2)notify():唤醒线程池中一个线程(任意).
3)notifyAll():唤醒线程池中的所有线程。
这些方法都必须定义在同步中,因为这些方法是用于操作线程状态的方法。必须要明确到底操作的是哪个锁上的线程。
为什么操作线程的方法wait notify notifyAll定义在了Object类中?
因为这些方法是监视器的方法。监视器其实就是锁。
锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。
18.多线程总结:
1)进程和线程的概念。
|--进程:
|--线程:
2)jvm中的多线程体现。
|--主线程,垃圾回收线程,自定义线程。以及他们运行的代码的位置。
3)什么时候使用多线程,多线程的好处是什么?创建线程的目的?
|--当需要多部分代码同时执行的时候,可以使用。
4)创建线程的两种方式。★★★★★
|--继承Thread
|--步骤
|--实现Runnable
|--步骤
|--两种方式的区别?
5)线程的5种状态。
对于执行资格和执行权在状态中的具体特点。
|--被创建:
|--运行:
|--冻结:
|--临时阻塞:
|--消亡:
6)线程的安全问题。★★★★★
|--安全问题的原因:
|--解决的思想:
|--解决的体现:synchronized
|--同步的前提:但是加上同步还出现安全问题,就需要用前提来思考。
|--同步的两种表现方法和区别:
|--同步的好处和弊端:
|--单例的懒汉式。
|--死锁。
7)线程间的通信。等待/唤醒机制。
|--概念:多个线程,不同任务,处理同一资源。
|--等待唤醒机制。使用了锁上的 wait notify notifyAll. ★★★★★
|--生产者/消费者的问题。并多生产和多消费的问题。 while判断标记。用notifyAll唤醒对方。 ★★★★★
|--JDK1.5以后出现了更好的方案,★★★
Lock接口替代了synchronized
Condition接口替代了Object中的监视方法,并将监视器方法封装成了Condition
和以前不同的是,以前一个锁上只能有一组监视器方法。现在,一个Lock锁上可以多组监视器方法对象。
可以实现一组负责生产者,一组负责消费者。
|--wait和sleep的区别。★★★★★
8)停止线程的方式。
|--原理:
|--表现:--中断。
9)线程常见的一些方法。
|--setDaemon()
|--join();
|--优先级
|--yield();
|--在开发时,可以使用匿名内部类来完成局部的路径开辟。
19. getClass方法和getName方法
getClass方法获取当前对象所属字节码文件对象
getName方法返回此Class对象所表示的实体(类,接口,数组类,基本类型或void)名称
例:
class Person
{
private int age;
Person(int age)
{
this.age=age;
}
}
class ObjectDemo
{
public static void main(String[] args)
{
Person p1=new Person(60);
Person p2=new Person(20);
Class clazz = p1.getClass();
System.out.println(p1.getClass()); //class Person
System.out.println(p1.getClass().getName()); //Person
20. StringBuffer
StringBuffer:就是字符串缓冲区,用于存储数据的容器。
特点:
1)长度是可变的;
2)可以存储不同类型的数据;
3)最终要转成字符串进行使用;
4)可以对字符串进行修改。
功能:
1)添加 append(data) insert(index,data)
2) 删除 delete(start,end) deleteCharAt(int index)
3) 查找 chartAt(index) indexOf(string) lastIndexOf(string)
4) 修改 replace(start,end,string) setCharAt(index,char)
21. StringBuffer与StringBuilder
jdk 1.5以后出现了功能和StringBuffer一模一样的对象,就是StringBuilder
不同的是:
StringBuffer是线程同步的,通常用于多线程。
StringBuilder是线程不同步的,通常用于单线程,它的出现提高效率。
22. 集合(主要包括Collection和Map两大接口体系,以及对 collection 进行迭代的迭代器接口Iterator)
1)集合类的由来:对象用于封装特有的数据,对象多了需要存储,如果对象的个数不确定,就使用集合容器进行存储。
2)集合的特点:用于存储对象的容器、集合的长度是可变的、集合中不能存储基本数据类型
3)集合容器因为内部的结构不同,有多种具体容器,不断的向上抽取,就形成了集合框架。框架的顶层
23. Collection接口
Collection的常见方法(没有修改芳法):
添加:boolean add(Object obj)
boolean addAll(Collection coll)
删除:boolean remove(Object obj)
boolean removeAll(Collection coll) //将两个集合中的相同元素从调用的集合中删除
void clear() //清空所有元素
判断:boolean contains(Object obj)
boolean containsAll(Collection coll) //调用的集合中是否完全包含被调用的集合
boolean isEmpty() // 判断是否有元素
获取:int size() // 返回集合中的元素个数
Iterator iterator() 取出元素的方式://迭代器
其他:boolean retainAll(Collection coll)://取交集,取出两个集合相同元素,删除不同元素,和removeAll相 反
Object [] toArray() : 将集合转为数组。toArray方法需要传入一个指定类型的数组。长度如何定义呢?
如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同size的数组。
如果长度大于集合的size,那么该方法会使用指定的数组,存储集合中的元素,其他位置默认为null。
所以建议,最后长度就指定为集合size。
24. Collection的两个常用接口:List和Set
Collection
|-- List:有序(存入和取出的顺序一致) , 元素都有索引(交表),元素可以重复。
|-- Set:无序,元素不能重复。
25. List特有的常见方法:有一个共性特点就是可以操作角标。
添加:void add(index,element)
void add(index,collection)
删除:Object remove(index)
修改:Object set(index,elment)
获取:Object get(index)
int indexOf(object)
int lastIndexOf(object)
List subList(from ,to)
在迭代器过程中,不要使用集合操作元素,容易出现异常。可以使用Iterator接口的子接口ListIterator来完成在迭代器中对元素的更多操作(增删改查)。只有List集合具备该迭代功能。
26. List接口的三个常用实现类:Vector,ArrayList,LinkedList
Vector:内部是数组数据结构,是同步的。增删,查询都很慢。
ArrayList:内部是数组数据结构,是不同步的。替代了Vector。查询的速度快。
LinkedList:内部是链(接)(列)表数据结构,是不同步的。增删元素的速度很快。
27. LinkedList的常用方法
addFirst()
addLast()
jdk 1.6
offerFirst()
offerLast()
getFirst() //获取但不移除,如果链表为空,抛出 NoSuchElementException
getLast()
jdk 1.6
peekFirst() //获取但不移除,如果链表为空,返回NULL
peekLast()
removeFirst() //获取并移除,如果链表为空,抛出 NoSuchElementException
removeLast() //获取并移除,如果链表为空,返回NULL
jdk 1.6
pollFirst()
pollLast()2
28. 堆栈:先进后出
队列:先进先出
29. 哈希表确定元素是否相同:
1)判断两个元素的哈希值是否相同,如果相同,再判断两个对象的内容是否相同
2)判断哈希值是否相同,其实判断的是对象的hashCode的方法。判断内容相同用的是equals方法。
注意:如果哈希值不同,是不需要判断equals。
30. Collection的另一个子接口Set
Set:元素不可以重复,是无序的。Set接口中的方法和Collection一致。
|-----HashSet :内部数据结构式哈希表,是不同步的。(唯一无序)
|-----LinkedHashSet:HashSet的子类,数据结构为哈希表和链接列表实现,数据是有序的,即取出的顺序和存进去的顺序一样。(唯一有序)
|-----TreeSet:可以对Set集合中的元素进行排序,是不同步的。判断元素唯一性的方式:就是根据比较方法返回结果是否为0,是0,就是相同元素,不存。
TreeSet对元素进行排序的方式一:让元素自身具备比较功能,元素需要实现Comparable接口,覆盖compareTo方法。
如果不要按照对象中具备的自然顺序进行排序。如果对象中不具备自然排序怎么办?
可以使用TreeSet集合的第二种排序方式:让集合自身具备比较功能,定义类实现Comparator接口,覆盖compare方法。将该类对象作为参数传给TreeSet集合的构造函数。也成比较器。
31. ArrayList判断两个元素是否相同,仅仅使用元素equals方法。
HashSet判断两个元素是否相同,使用元素的hashCode和equals方法。
32. 泛型
jdk 1.5出现的安全机制
好处:
1.将运行时期的问题ClassCastException转到了编译时期。
2.避免了强制转换的麻烦。
什么时候用:
当操作的引用数据类型不确定的时候,就使用<>。将要操作的引用数据类型传入即可。其实<>就是一个用于接收具体引用数据类型的参数范围。不能存基本数据类型。
在程序中,只要用到了带有<>的类或接口,就要明确传入的具体应用数据类型。
泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全。运行时会将泛型去掉,生成的class文件中是不带泛型的。这个称为泛型的擦除。为什么擦除呢?因为为了兼容运行的类加载器。
泛型的补偿:在运行时,通过获取元素的类型进行转换动作,不用使用者再强制转换了。
1)泛型类:在jdk 1.5后,使用泛型来接受类中要操作的引用数据类型,这就是泛型类。
什么时候用?当类中操作的引用数据类型不确定的时候,就使用泛型类来表示。
2)泛型方法:泛型还可以使用在方法上。当方法为静态时,不能访问同类上定义的泛型。如果静态方法使用泛型,只能将泛型定义在方法上。<>放在修饰符后,返回值类型前。
3)泛型接口:将泛型定义在接口上。
4)泛型的通配符:?表示可以存一切未知类型
可以对类型进行限定:
? extends E 表示可以接收E类型及其子类型对象。即上限通常用来存储元素,因为这样取出都是按照上限类型来运算的。不会出现类型安全隐患。
? super E 表示可以接受E类型及其父类型对象。即下限 通常对集合中的元素进行取出操作时使用下限。
33. Collection集合的一些小技巧
1)分别在何时用
需要唯一吗?
需要:Set
需要指定顺序吗?
需要:TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
2)如何记住每个容器的结构和所属体系
看名字:后缀名就是该集合所属体系,前缀名就是该集合的数据结构。
看到array就要想到数组,就要想到查询快,有角标;
看到link就要想到链表,就要想到增删快,就要想到add,get,remove+first last方法
看到hash就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖hashcode和equals方法
看到tree就要想到二叉树,就要想到排序,就要想到两个接口Comparable,Comparator
而且,通常这些常用的集合容器是不同步的。
List
|-----ArrayList
|-----LinkedList
Set
|-----HashSet
|-----TreeSet
34. Map
特点:
1)一次添加一对元素,Collection一次添加一个元素。
2) Map也称为双列集合,Collection也成为单列集合。
3)其实Map集合中存储的就是键值对。
4)Map集合中必须保证键的唯一性。
常用方法:
1)添加
value put(key,value) : 返回前一个和key关联的值,如果没有返回null。存相同键,值会覆盖
2)删除
void clear() : 清空map集合
value remove(key) : 根据指定的key删除这个键值对
3)判断
boolean containsKey(key) : 包含键吗
boolean containsKey(key) : 包含值吗
boolean isEmpty() : 有键值对吗
4)获取
value get(key) : 通过键获取值,若果没有该键返回null。当然可以通过返回null,来判断是否包含指定建。
int size() : 获取键值对个数
keySet() : 返回此映射中包含的key即键的 set 视图
entrySet() : 返回此映射中包含的映射关系的 set 视图
Collection values() :返回此映射中包含的值的 collection 视图
Map集合常用子类:
Hashtable : 内部结构是哈希表,是同步的。不允许null作为键和值。
|-------Properties : 用来存储键值对型的配置文件的信息。可以和IO技术结合。
HashMap :内部结构是哈希表,是不同步的。允许null作为键和值(无序)。
|-------LinkedHashMap:取出顺序和存入顺序一致(自然有序)
TreeMap:内部结构是二叉树,是不同步的。可以对Map集合中的键进行排序(可以排序)。
35. Collections类
它是集合框架的工具类,里面的方法都是静态的,可以直接用类名调用
1)排序 sort()
sort(list) : 根据元素的自然顺序 对指定列表按升序进行排序。
sort(list, 比较器) :根据指定比较器产生的顺序对指定列表进行排序。
2)换位
swap(list, int i, int j) :在指定列表的指定位置处交换元素
3)折半
binarySearch(list,key) :使用二分搜索法搜索指定列表,以获得指定对象
例:binarySearch(list,"cba")
4)最值
max(coll):根据元素的自然顺序,返回给定 collection 的最大元素。
min(coll) :根据元素的自然顺序,返回给定 collection 的最小元素。
max(coll, 比较器) :根据指定比较器产生的顺序,返回给定 collection 的最大元素。
5)逆序
reverse(list) 反转指定列表中元素的顺序。
reverseOrder() 返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
reverseOrder(比较器) 返回一个比较器,它强行逆转指定比较器的顺序。
6)替换
replaceAll(list, oldVal, newVal) 使用另一个值替换列表中出现的所有某一指定值。
36. Arrays : 集合框架的工具类。里面的方法都是静态的。
1) sort() :对指定类型的数组按数字升序进行排序
2)binarySearch():使用二分搜索法来搜索指定类型的数组,以获得指定的值
3)copy():复制指定的数组,截取或用指定类型填充(如有必要),以使副本具有指定的长度
4)equals(int[] a, int[] a2) :如果两个指定的 int 型数组彼此相等
5)toString(long[] a) :返回指定数组内容的字符串表示形式
6)List asList(Array a) :返回一个受指定数组支持的固定大小的列表。
即将数租转为List集合,好处是可以使用集合的方法操作数租中的元素。但是不能使用集合的增删方法,因为数组的长度是固定的。
如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储
如果数组中的元素是基本数据类型,那么会将该数组(对象)作为集合中的元素进行存储
37. foreach语句
说明:JDK 5.0之后的新特性,简化书写
格式:for(类型 变量 : Collection集合|数组 )
例子:for(String s : list)
传统for和高级for(foreach语句)的区别:
传统for可以完成对语句执行很多次,因为可以定义控制循环的增量和条件;
高级for是一种简化形式,它必须有被遍历的目标,该目标要么是数组,要么是Collection单列集合;
对数组的遍历如果仅仅是获取数组中的元素,可以使用高级for,如果要对数组的角标进行操作建议使用传统for
38. 函数可变参数
说明:JDK 5.0之后的新特性,简化了调用者的书写。
定义:其实就是一个数组,但是接收的是数组中的元素,自动将这些元素封装成数组。
注意:可变参数类型,必须定义在参数列表的结尾。
例子:public static int newAdd(int... count) 正确
public static int newAdd(int a, int... count) 正确
public static int newAdd(int... count,int a) 错误
39. System类
System 类包含一些有用的类字段(属性)和方法,它不能被实例化。所以类中的属性和方法都是静态的。
1)属性
out:“标准”输出流
in: “标准”输入流
2)常见方法
long currentTimeMillis() :返回以毫秒为单位的当前时间。返回:当前时间与协调世界时 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。
Properties getProperties():获取当前的系统属性,并存储到Properties集合中。properties集合中存储的都是String类型的键和值,最好使用他自己的存储和取出的方法来完成元素的操作。
40. Runtime类
该类没有构造方法摘要,该类不可以创建对象。又发现还有非静态方法,说明该类应该提供静态的返回该类对象的方法,而且只有一个,说明该类使用了单例设计模式。
1)getRuntime() :返回与当前 Java 应用程相关的运行时对象。
2) Process exec(String command) :在单独的进程中执行指定的字符串命令。
41. Math类
提供了操作数学运算的方法,都是静态的。
ceil(8.6):向上取整返回9
floor(8.6):向下取整返回8
round(8.6):四舍五入返回8
pow(a,b) :返回a的b次幂
random():返回0到1的随机数
42. Date类
Date():分配 Date 对象并初始化此对象,以表示分配它的时间
1)日期对象和毫秒值之间的转换
a.毫秒值转日期对象
可以通过Date对象的构造方法new Date(timeMillis);
还可以公国setTime设置。因为可以通过Date对象的方法对该日期对象中的各个字段(年月日等)进行操作
b.日期对象转毫秒值
getTime方法。因为可以通过具体的数值进行运算
2)日期对象转字符串
a.使用DateFormat类中的format方法,获取日期格式对象,具备默认的风格
例:
Date date = new Date();
//获取日期格式对象,具备默认的风格
DateFormat dateformat = DateFormat.getDateInstance(DateFormat.LONG);
dateformat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
String str_date = dateformat.format(date);
System.out.println(str_date);
b.使用DateFormat类的子类SimpleDateFormat的构造方法SimpleDateFormat,可以自定义风格
例:
Date date = new Date();
DateFormat dateformat = DateFormat.getDateInstance(DateFormat.LONG);
dateformat=DateFormat.getDateTimeInstance(DateFormat.LONG,DateFormat.LONG);
//获取日期格式对象,具备自定义格式
dateformat = new SimpleDateFormat("yyyy--MM--dd");
String str_date = dateformat.format(date);
System.out.println(str_date);
3)将日期格式的字符串转为日期对象
使用的事DateFormatL类中的parse方法。
43. calendar类
Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar 的 getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化。
常用方法:set,get,add等
44. new和getInstance()的区别
1)new的使用:
如Object _object = new Object(),这时候,就必须要知道有第二个Object的存在,而第二个Object也常常是在当前的应用程序域中的,可以被直接调用的。
2)GetInstance的使用:
在主函数开始时调用,返回一个实例化对象,此对象是static的,在内存中保留着它的引用,即内存中有一块区域专门用来存放静态方法和变量,可以直接使用,调用多次返回同一个对象。
3)两者区别对照:
大部分类(非抽象类/接口/屏蔽了constructor的类)都可以用new,new就是通过生产一个新的实例对象,或者在栈上声明一个对象,每部分的调用用的都是一个新的对象。
getInstance是少部分类才有的一个方法,各自的实现也不同。getInstance在单例模式(保证一个类仅有一个实例,并提供一个访问它的全局访问点)的类中常见,用来生成唯一的实例,getInstance往往是static的。
45.IO流
1)定义:即输入流和输入流,是相对于内存设备而言的。将外设中的数据读取到内存中为输入,将内存的数据写入到外设中为输出。
2)体系
字节流的常用基类(顶层父类):InputStream、OutputStream
字符流的常用基类(顶层父类):Reader、Writer (如果要操作文字数据优先考虑字符流,而且要将数据从内存写到硬盘上,要使用字符流中的输出流Writer)
这些体系的子类都以父类子类名作为后缀,而且子类名的前缀就是该对象的功能。
3)FileWriter类从OutputStreamWriter类中继承的flush方法和close方法的区别
flush : 保存
close:保存并关闭
4)续写
FileWriter fw = new FileWriter("demo.txt",true);
在构造方法中加入参数true,可以是文件续写。
5)字符流的缓冲区
缓冲区的出现提高了对数据的读写效率。对应类BufferedReader,BufferedWriter
BufferedReader:readLine() 读取一个文本行
BufferedWriter:newLine() 写入一个行分隔符
6)装饰模式及其和继承的区别
定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆。对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
设计初衷:通常可以使用继承来实现功能的拓展,如果这些需要拓展的功能的种类很繁多,那么势必生成很多子类,增加系统的复杂性,同时,使用继承实现功能拓展,我们必须可预见这些拓展功能,这些功能是编译时就确定了,是静态的。
异同点:都可以进行功能的扩展增强,使用装饰模式相比用生成子类方式达到功能的扩充显得更为灵活。
特点:装饰类和被装饰类都必须所属同一个接口或者父类。
7)字节流
不近可以操作字符,还可以操作其他媒体文件(ma3,jpg,dvd等)
FileInputStream和FileOutputStream
BufferedInputStream和BufferedOutputStream
46.Java关键字transient和volatile
transient和volatile两个关键字一个用于对象序列化,一个用于线程同步,都是Java中比较高阶的话题,简单总结一下。
1)transient是类型修饰符,只能用来修饰字段。在对象序列化的过程中,标记为transient的变量不会被序列化。
2)volatile也是变量修饰符,只能用来修饰变量。volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
47. 方法的使用技巧
一是:split(regex),参数为要分隔的字符串或者正则表达式。
二是:ss.split(regex, limit)。此方法可以的第二个参数一般不太常用,
这两个方法api给的解释是:limit 参数控制模式应用的次数,因此影响所得数组的长度。如果该限制 n 大于 0,则模式将被最多应用 n - 1 次,数组的长度将不会大于 n,而且数组的最后一项将包含所有超出最后匹配的定界符的输入。如果 n 为非正,那么模式将被应用尽可能多的次数,而且数组可以是任何长度。如果 n 为 0,那么模式将被应用尽可能多的次数,数组可以是任何长度,并且结尾空字符串将被丢弃。
两个方法的区别是split(regex)返回变长的数组,就是可以分割为多少项就返回多长的数组