java.lang包源码学习
Java.lang包接口摘要
Iterable 接口
参考链接
iterable 的主要作用是实现for each方法,遍历集合的工作依然是iterator来做
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
//遍历例子
list.forEach(s->{
System.out.println(s)
})
Readable接口
参考链接
Readable接口就是为了Scanner类专门创建的一个接口,使得Scanner的入口参数不必限于某个类。实现Readable接口要只需是实现public int read(CharBuffer cb)方法。当方法返回-1时候Scanner类停止读取。
Runnable 接口
参考链接
我们实现多线程,有两种方式, 一种是继承Thread类,一种是实现Runnable接口,但是启动线程必须依赖thread的start方法。
有经验的程序员都会选择实现Runnable接口 ,其主要原因有以下两点:
首先,java只能单继承,因此如果是采用继承Thread的方法,那么在以后进行代码重构的时候可能会遇到问题,因为你无法继承别的类了。
其次,如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。参考链接
Java.lang 包下类摘要
Integer类
Integer是int的包装类,int 常用于局部变量和参数传递的一些简单的数据存储和传递,Integer是包装类,在-128-127之间时Integer和int是一致的,在这个范围之外Integer就会自动创建对象来进行操作了,Integer 提供了非常多的方法来处理int型数据参考链接
常用方法参考链接
- int compareTo(Integer anotherInteger) //在数字上比较两个 Integer 对象。
- boolean equals(Object obj) //比较此对象与指定对象。
- double doubleValue() //以 double 类型返回该 Integer 的值。
- float floatValue() //以 float 类型返回该 Integer 的值。
- int intValue() //以 int 类型返回该 Integer 的值。
- long longValue() //以 long 类型返回该 Integer 的值。
- int parseInt(String s) //将字符串转换成int
- String toBinaryString(int i) //以二进制(基数 2)无符号整数形式返回一个整数参数的字符串表示形式。
- String toHexString(int i) //以十六进制(基数 16)无符号整数形式返回一个整数参数的字符串表示形式。
- String toOctalString(int i) //以八进制(基数 8)无符号整数形式返回一个整数参数的字符串表示形式。
- String toString() //返回一个表示该Integer值的String对象。
- Integer valueOf(int i) 返回一个表示指定的 int 值的 Integer 实例。
- Integer valueOf(String s) 返回保存指定的 String 的值的 Integer 对象。
- Integer valueOf(String s, int radix) 返回一个 Integer 对象
装箱和拆箱
- 基本数据类型转换为包装类的过程称为装箱
- 包装类变为基本数据类型的过程称为拆箱
public class Demo {
public static void main(String[] args) {
int m = 500;
Integer obj = m; // 自动装箱
int n = obj; // 自动拆箱
System.out.println("n = " + n);
Integer obj1 = 500;
System.out.println("obj等价于obj1返回结果为" + obj.equals(obj1));
}
}
String 类
String类用于处理字符串的一切问题
特征
- String类是final的,不可被继承;
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
- String类本质是字符型数组char[ ],并且值不可改变;
private final char value[];
- 创建字符串的方式很多,归纳起来有三类:
第一类,利用new关键字创建一个String对象,如:String s1 = new String("abc");
第二类,利用特性3直接创建,如:String s2 = "abc";
第三类,利用特性4串联生成新的字符串,如:String s3 = "a" + "b" + "c";
string 常用方法参考链接
- length() 字符串的长度
- charAt() 截取一个字符 //ch=“abc”.charAt(1); 返回’b’
- toCharArray() String转换成char数组
- substring()
- trim() 去掉起始和结尾的空格
StringBuffer
string的字符串长度是固定的,StringBuffer用于处理可变字符串,是一个容器,区别去String的是,StringBuffer是一个对象,所有的这些方法处理的都还是StringBuffer这个对象,而String可能是不同的对象。
StringBuffer s0=new StringBuffer();分配了长16字节的字符缓冲区
StringBuffer s1=new StringBuffer(512);分配了512字节的字符缓冲区
StringBuffer s2=new StringBuffer("Happy new year!");在字符缓冲区中存放字符串"Happy new year!",另外,后面再留了16字节的空缓冲区。
常用方法参考链接
- append()添加
作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接
synchronized决定StringBuffer是线程安全的
public synchronized StringBuffer append(int i) {
- insert()方法
接受boolean,char,double,float,int,long,string等各种值
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
append和insert的区别:
append默认在末尾添加,insert可以在指定位置添加
StringBuilder
StringBuilder和StringBuffer内部代码几乎一样,只是StringBuffer的所有方法都被关键字synchronized修饰,也就是说它是线程安全的
Double 类
是double的包装类,用于处理双精度数据的类
public final class Double extends Number implements Comparable<Double> {
构造方法
Double类提供了两种构造方法
Double double1 = new Double(5.456); // 以 double 类型的变量作为参数创建 Double 对象
Double double2 = new Double("5.456"); // 以 String 类型的变量作为参数创建 Double 对象
常用方法参考链接
Double和double的区别参考链接
double是基本数据类型,Double是原始数据类型
double没有方法,Double有自己的属性和方法
double只创建引用,Double创建对象
集合类不能存放double,只能存放Double
double存放在栈中,Double存放在堆中
栈的存取速度要高于堆
Float 类
Float提供浮点类型的数据处理类
public final class Float extends Number implements Comparable<Float> {
Float类和Double的方法基本类似,主要的都是比较和返回int \long \short\double\float等基本数据的值继承子number抽象类的抽象方法
Float的构造方法参考链接
- Float(double value):构造一个新分配的 Float 对象,它表示转换为 float 类型的参数。
- Float(float value):构造一个新分配的 Float 对象,它表示基本的 float 参数。
- Float(String s):构造一个新分配的 Float 对象,它表示 String 参数所指示的 float 值。
Float float1 = new Float(3.14145); // 以 double 类型的变量作为参数创建 Float 对象
Float float2 = new Float(6.5); // 以 float 类型的变量作为参数创建 Float 对象
Float float3 = new Float("3.1415"); // 以 String 类型的变量作为参数创建 Float 对象
float和double的区别参考链接
float 单精度浮点数在机内占 4 个字节,用 32 位二进制描述。
double 双精度浮点数在机内占 8 个字节,用 64 位二进制描述。
Short 类
short是数值型数据类型,默认值是0,一个short变量是int型变量所占空间的二分之一,long是int 的2倍。
Short类继承抽象类Number实现Comparable接口,基本方法都差不多,不同的点在于数据类型不同而已。
public final class Short extends Number implements Comparable<Short> {
Short构造方法参考链接
public Short(short value)//提供short类型的数据构造对象
public Short(String value)//提供String类型的数据构造对象
Long 类
Long也是继承和实现Number和Comparable
public final class Long extends Number implements Comparable<Long> {
long主要用于处理非常大的整数的变量,也可以简单理解为,当我们最常用的int类型满足不了我们时我们使用long来进行数据类型处理,long是in t的两倍,int 32位,long64位,所表示的范围也是相应的两倍。
Long构造方法
public Long(long value)//提供long型变量
public Long(String value)//提供String型变量
Java基础数据类型位数和取值范围参考链接
基本类型:byte 二进制位数:8
包装类:java.lang.Byte
最小值:Byte.MIN_VALUE=-128
最大值:Byte.MAX_VALUE=127
基本类型:short 二进制位数:16
包装类:java.lang.Short
最小值:Short.MIN_VALUE=-32768
最大值:Short.MAX_VALUE=32767
基本类型:int 二进制位数:32
包装类:java.lang.Integer
最小值:Integer.MIN_VALUE=-2147483648
最大值:Integer.MAX_VALUE=2147483647
基本类型:long 二进制位数:64
包装类:java.lang.Long
最小值:Long.MIN_VALUE=-9223372036854775808
最大值:Long.MAX_VALUE=9223372036854775807
基本类型:float 二进制位数:32
包装类:java.lang.Float
最小值:Float.MIN_VALUE=1.4E-45
最大值:Float.MAX_VALUE=3.4028235E38
基本类型:double 二进制位数:64
包装类:java.lang.Double
最小值:Double.MIN_VALUE=4.9E-324
最大值:Double.MAX_VALUE=1.7976931348623157E308
基本类型:char 二进制位数:16
包装类:java.lang.Character
最小值:Character.MIN_VALUE=0
最大值:Character.MAX_VALUE=65535
Byte 类
byte一个字节,8位,取值范围:-128-127,
public final class Byte extends Number implements Comparable<Byte> {
Byte构造方法
Byte提供两种构造方法,分别是Byte和String
Byte b1 = new Byte(5);
Byte b2 = new Byte("5");
private static class ByteCache {
private ByteCache(){}
ByteCache
private static class ByteCache {
private ByteCache(){}
static final Byte cache[] = new Byte[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Byte((byte)(i - 128));
}
}
这是Byte的一个内部类,而且是私有的,只能在本类中调用。可以看到在这个类的内部定义了一个Byte类型的数组,数组的长度刚好是Byte类中最小值到最大值之间的长度(负数128个,正数127个加上0共256个)。在静态代码块中创建了这256个对象放到cache数组中,之前也介绍了静态代码块在类一加载的时候就会执行。这里是将byte类型所有的可能值(对于byte来说其实它的可能值就是从-128到127,一共256个)缓存起来,只能创建256个Byte对象就可以表示所有可能的byte。而且这些都是静态且final的,避免重复的实例化和回收。参考链接
数值类型包装类对比:
- 都继承了Number,实现Comparable
- 都提供自己和String的构造方法
Boolean 类
boolean就true和false,布尔类型的变量就没有数值类型的XXXValue()了,依然有比较和其它常规的方法。
public final class Boolean implements java.io.Serializable,Comparable<Boolean>
{
Boolean构造方法
Boolean(boolean boolValue);
Boolean(String boolString);
其中 boolValue 必须是 true 或 false(不区分大小写),boolString 包含字符串 true(不区分大小写),那么新的 Boolean 对象将包含 true;否则将包含 false。参考链接
Character 类
Character 类是字符数据类型 char 的包装类。
public final class Character implements java.io.Serializable,Comparable<Character> {
Character的构造方法只提供char一种方式
-
isLetter() 方法
isLetter() 方法用于判断指定字符是否为字母。
语法:boolean isLetter(char ch)
其中ch = 要测的字符;当字符为字母时,则返回 true,否则返回 false。(以下ch都为要测的字符) -
isDigit() 方法
isDigit() 方法用于判断指定字符是否为数字,如果字符为数字,则返回 true;否则返回 false。
语法:public static boolean isDigit(char ch) -
isWhitespace() 方法
isWhitespace() 方法用于判断指定字符是否为空白字符,空白符包含:空格、tab 键、换行符,如果字符为空白字符,则返回 true;否则返回 false。
语法:boolean isWhitespace(char ch) -
isUpperCase() 方法
isUpperCase() 方法用于判断指定字符是否为大写字母,如果字符为大写,则返回 true;否则返回 false。
语法:boolean isUpperCase(char ch) -
isLowerCase() 方法
isLowerCase() 方法用于判断指定字符是否为小写字母,如果字符为小写,则返回 true;否则返回 false。
语法:boolean isLowerCase(char ch) -
toUpperCase() 方法
toUpperCase() 方法用于将小写字符转换为大写,如果有的话,返回转换后字符的大写形式;否则返回字符本身。
语法:char toUpperCase(char ch) -
toLowerCase() 方法
toLowerCase() 方法用于将大写字符转换为小写,如果有的话,返回转换后字符的小写形式;否则返回字符本身。
语法:char toLowerCase(char ch) -
toString() 方法
toString() 方法用于返回一个表示指定 char 值的 String 对象。结果是长度为 1 的字符串,仅由指定的 char 组成。
语法:String toString(char ch)
Number 类
数字类型的抽象类 Number 是 BigDecimal、BigInteger、Byte、Double、Float、Integer、Long 和 Short 类的超类。
public abstract int shortValue();
public abstract int intValue();
public abstract int longValue();
public abstract int floatValue();
public abstract int doubleValue();
public abstract int byteValue();
提供了6个数值型的抽象方法,在其封装类中都继承了Number类,实现了其抽象方法
Object 类
Object 类是所有类的父类,Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类,这句话的意思就是我们定义的任何类都是
public class Person extends Object{}//但是一般默认不写
Object的所有方法
- toString() 方法
默认返回类名@对像的散列值
类中如果重写了toString()方法,输出充写方法 - getClass()方法
返回一个Class,可以继续获取类的一些信息,比如obj.getClass().getName()//返回类名字
getClass()也是一个native方法,返回的是此Object对象的类对象/运行时类对象Class<?>。效果与Object.class相同。
首先解释下"类对象"的概念:在Java中,类是是对具有一组相同特征或行为的实例的抽象并进行描述,对象则是此类所描述的特征或行为的具体实例。作为概念层次的类,其本身也具有某些共同的特性,如都具有类名称、由类加载器去加载,都具有包,具有父类,属性和方法等。于是,Java中有专门定义了一个类,Class,去描述其他类所具有的这些特性,因此,从此角度去看,类本身也都是属于Class类的对象。为与经常意义上的对象相区分,在此称之为"类对象"。参考链接
- clone()方法
克隆一个完全一样的对像
public class ObjectTest {
public static void main(String[] args) {
Object o1 = new Object();
// The method clone() from the type Object is not visible
Object clone = o1.clone();
}
}
- hashcode()方法
返回一个对象的哈希码,用于判断两个对象是否相等。主要作用体现在集合里判断集合中是否存在相同的对象。
以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode()方法,需要将Set进行一次遍历,并逐一用equals()方法判断两个对象是否相等,此种算法时间复杂度为o(n)。通过借助于hasCode方法,先计算出即将新加入对象的哈希码,然后根据哈希算法计算出此对象的位置,直接判断此位置上是否已有对象即可。
- wait(…) / notify() / notifyAll()方法
(wait和sleep的区别是,wait释放了锁,sleep仍然持有锁)
wait():调用此方法所在的当前线程等待,直到在其他线程上调用此方法的主调(某一对象)的notify()/notifyAll()方法。
wait(long timeout)/wait(long timeout, int nanos):调用此方法所在的当前线程等待,直到在其他线程上调用此方法的主调(某一对象)的notisfy()/notisfyAll()方法,或超过指定的超时时间量。
notify()/notifyAll():唤醒在此对象监视器上等待的单个线程/所有线程。
- finalize()方法
finalize方法主要与Java垃圾回收机制有关。
finalize方法被定义成一个空方法,为什么要如此定义呢?finalize方法的调用时机是怎么样的呢?
首先,Object中定义finalize方法表明Java中每一个对象都将具有finalize这种行为,其具体调用时机在:JVM准备对此对形象所占用的内存空间进行垃圾回收前,将被调用。由此可以看出,此方法并不是由我们主动去调用的(虽然可以主动去调用,此时与其他自定义方法无异)。
Class 类
JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息,包括类名、包名、父类、实现的接口、所有方法、字段等,因此,如果获取了某个Class实例,我们就可以通过这个Class实例获取到该实例对应的class的所有信息。参考链接
获取Class的实例的三种方法:
- 类名.class
Class cls = String.class;
- 对象名.getClass()
String s = "Hello";
Class cls = s.getClass();
- Class,forName(“类路径”)
Class cls = Class.forName("java.lang.String");
得到实例之后就是访问通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
s.getClass().getNamne();//获取类名
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
其实反射什么就是,在通过上面三种方法获得某个类的实例之后通过Class这个类提供的方法就可以访问任何一个类的信息,属性和方法(不是对象.属性.方法这种调用)
比如我建立一个String类型的实例:
String str=new String("hello")//建一个对象
Class am=str.getClass();//得到一个class实例
am.getFields();//获得String这个类的所有public的属性
System 类
System类是在Java程序中作为一个标准的系统类,实现了控制台与程序之间的输入输出流,系统的初始化与获取系统环境变量、数组的复制、返回一个精准的时间以及一些简单的对虚拟机的操作等。它是一个与Class类一样的直接注册进虚拟机的类,也就是直接与虚拟机打交道的类:参考链接
- System.in
public final static InputStream in = null;
返回的是一个InputStream类型
- System.out
public final static PrintStream out = null;
返回的是一个PrintStream类型,那么我们就可以访问PrintStream的方法
比如最常见的:
System.out.println()
print/println(基本数据类型)都是PrintStream类的方法
- getproperty()方法参考链接
System.getProperty("属性名")
Enum 类
枚举是一个类,可以把常量放在一个枚举类中
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
定义枚举类
package enumtest;
public enum WeekEnum {
// 因为已经定义了带参数的构造器,所以在列出枚举值时必须传入对应的参数
SUNDAY("星期日"), MONDAY("星期一"), TUESDAY("星期二"), WEDNESDAY("星期三"),
THURSDAY("星期四"), FRIDAY("星期五"), SATURDAY("星期六");
// 定义一个 private 修饰的实例变量
private String date;
// 定义一个带参数的构造器,枚举类的构造器只能使用 private 修饰
private WeekEnum(String date) {
this.date = date;
}
// 定义 get set 方法
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
}
Enum的自带属性参考链接
- name //名字
- ordinal //枚举定义中出现的顺序
Math 类
常用的数学处理类
比如:
- abs() //绝对值
- min() //最小值
- max() // 最大值等
Process 类
Process 类提供了执行从进程输入、执行输出到进程、等待进程完成、检查进程的退出状态以及销毁(杀掉)进程的方法。参考链接
Process类方法摘要
创建Process对象(进程)的两种方法
- ProcessBuilder.start()
- Runtime.exec
ProcessBuilder 类
ProcessBuilder是一个后起之秀1.5才添加的,一开始是没有这个类的,只有Process,我们知道运行外部程序,我们适用RunTime().exec()来运行,但是当我们要动态运行外部程序的时候Process就显得不太够用,ProcessBuilder的功能也比Process的要多,比如可以设置当前工作目录,更改环境参数。参考链接
说简单点:
ProcessBuilder可以以一组明确的环境变量来启动一个进程。
ProcessBuilder基本方法参考链接
- 创建一个进程
public static void main(String[] args) throws Exception {
ProcessBuilder pBuilde=new ProcessBuilder("notepad.exe");
pBuilde.start();
}
//执行代码之后就打开记事本了
- 常用方法
public static void main(String[] args) throws Exception {
ProcessBuilder pBuilde=new ProcessBuilder("notepad.exe");
System.out.println(pBuilde.environment());
//可以执行包含的命令输出[notepad.exe]
System.out.println(pBuilde.command());
//当前的工作目录,没有指定为null
System.out.println(pBuilde.directory());
//通过start方法开启一个新进程
// pBuilde.start();
//替代方法
Runtime runtime = Runtime.getRuntime();
runtime.exec("notepad.exe");
}
Runtime 类
可以使用Runtime类取得JVM系统信息,或者使用gc()方法释放掉垃圾空间,还可以使用此类运行本机的程序
使用
Runtime run = Runtime.getRuntime();
run.start()
常用方法
- public static Runtime getRuntime() 普通方法 用于取得Runtime类的实例
- public long freeMemory() 普通方法 用于返回Java虚拟机中的空闲内存
- public long maxMemory() 返回JVM的最大内存量
- public void gc() 运行垃圾回收器。释放空间。
- public Process exec(String command) throws IOException 执行本机命令一旦取得实例后,以上的方法就可以进行操作了。参考链接
Runtime run = Runtime.getRuntime(); // 通过Runtime类的静态方法进行实例化操作
System.out.println("JVM最大内存量:" + run.maxMemory()) ; // 观察最大的内存,根据机器的不同,环境也会有所不同
System.out.println("JVM空闲内存量:" + run.freeMemory()) ; //取得程序运行的空闲内存
run.exec("notepad.exe") ;
Thread类
thread实现了Runnable接口,
public class Thread implements Runnable {
线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、time waiting、waiting、消亡(dead)。参考链接
当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,譬如程序计数器、Java栈、本地方法栈都是线程私有的,所以需要为线程分配一定的内存空间),只有线程运行需要的所有条件满足了,才进入就绪状态。
当线程进入就绪状态后,不代表立刻就能获取CPU执行时间,也许此时CPU正在执行其他的事情,因此它要等待。当得到CPU执行时间之后,线程便真正进入运行状态。
线程在运行状态过程中,可能有多个原因导致当前线程不继续运行下去,比如用户主动让线程睡眠(睡眠一定的时间之后再重新执行)、用户主动让线程等待,或者被同步块给阻塞,此时就对应着多个状态:time waiting(睡眠或等待一定的事件)、waiting(等待被唤醒)、blocked(阻塞)。
当由于突然中断或者子任务执行完毕,线程就会被消亡。
具体对应的Java方法是:参考链接
Thread构造方法
Thread() 分配一个新的线程对象
Thread(String name) 分配一个指定名字的新的线程对象
Thread(Runnable target) 分配一个带有指定目标新的线程对象
Thread(Runnable target,String name) 分配一个带有指定目标新的线程对象并指定名字
Thread的几个常见属性
1)getId
用来得到线程ID
2)getName和setName
用来得到或者设置线程名称。
3)getPriority和setPriority
用来获取和设置线程优先级。
4)setDaemon和isDaemon
用来设置线程是否成为守护线程和判断线程是否是守护线程。
Thread常用方法
- start方法
首先是new一个Thread对象,如果对象分配到资源后进入可以就绪状态(Runnable),当调用start方法后并且获得了CPU资源那么该线程就进入到运行状态了 - run方法
所有线程执行开始都是执行run方法体内的内容,所以继承Thread和Runnable必须重写run方法,start启动之后默认执行run方法 - sleep方法
让线程睡眠一定时间,让CPU去执行其他的任务。 - getName()
获得当前线程的名字 - currentThread()
获取当前线程。
。。。。。。