Java学习总结——Java 常用类库

拾伍——储存类的仓库

一、API 的概念

Java 类库就是 Java API( 应用程序接口 ),是系统提供的已实现的标准类集合,使用 Java 类库可以完成涉及字符串处理、图形、网络等多方面的操作。

API( Application Programming Interface )就是应用程序编程接口,它是软件系统不同组成部分衔接的约定。API 可以理解为是一些预先定义的函数。其设计目的在于,可以提供应用程序得以访问某些特定软件或硬件的能力,而又无需获知这些软硬件的源码,也无需理解它们的内部工作机制细节。这既方便了应用开发人员,同时也能在一定程度上,保护了软硬件的知识产权。

假设现在要编写一个机器人程序,去控制一个机器人的行为,程序需要向机器人发出各种行动命令,如果有编程经验的人会知道,机器人厂商一定会提供一些控制这些机器人的 Java 类,该类中就有操纵杆机器人各种动作的方法,只需要为每个机器人安排一个该类的实例对象,再调用这个对象的各种方法,机器人就会去执行各种动作。这个 Java 类就是机器人厂家提供的应用程序编程的接口,厂家就可以对这些 Java 类美名其曰:Xxx Robot API( 也就是 Xxx 厂家的机器人 API )。好的机器人厂家不仅会提供 Java 程序用的 Robot API,也会提供 Windows 编程语言( 如 VC++ )用的 Robot API,以满足各类编程人员的需要。

二、基本数据类型的包装类

Java 对数据既提供基本数据的简单类型,也提供了相应的包装类。使用基本数据类型,可以改善系统的性能,也能够满足大多数的应用需求。但基本数据类型不具有对象的特性,不能满足某些特殊的需求。从 JDK 中可以知道, Java 中的很多类的很多方法的参数类型都是 Object,即这些方法接收的参数都是对象,同时,又需要用这些方法来处理基本数据类型的数据,这时就要用到包装类。比如,用 Integer 类来包装整数。

Java 中的基本数据类型共有 8 种,name与之相对应的基本数据类型包装类也同样有 8 种,下表列出其对应关系:

基本数据类型 基本数据类型包装类
int Integer
char Character
float Float
double Double
byte Byte
long Long
short Short
boolean Boolean

举例:

//使用包装类
class IntegerDemo
{
	public static void main(String[] args)
	{
		String a = "123";	//定义一个字符串
		int i = Integer.parseInt(a);	//将字符串转换成整型
		i++;	//将i在原有数值上加1
		System.out.println(i);	//输出i的值
	}
}

此例使用 Integer 类中的 parseInt() 方法,将一个字符串转换成基本数据类型。

1.装箱与拆箱

所谓装箱,就是把基本数据类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,例如我们可以把 int 型包装成 Integer 类的对象,或者把 double 包装成 Double 等。

所谓拆箱,就是跟装箱的方向相反,将 Integer 及 Double 这样的引用类型的对象重新简化为值类型的数据。

JDK 1.5 之前使用手动方式进行装箱和拆箱的操作,JDK 1.5 之后可自动进行装箱和拆箱的操作。

举例:

//包装类的使用
public class Int_Integer
{
	public static void main(String[] args)
	{
		Integer x = new Integer(10);	//基本类型变为包装类,装箱
		int temp = x.intValue();	//包装类变为基本类型,拆箱
		System.out.println(temp * temp);	//输出 temp与 temp的乘积
	}
}

装箱操作:将基本数据类型变为包装类,利用各个包装类的构造方法完成。

拆箱操作:将包装类变为基本数据类型,利用 Number 类的 xxxValue() 方法完成。

2.基本数据类型与字符串的转换

使用包装类有一个最大的操作特点:可以将字符串变为指定的基本类型,使用的方法如下( 部分 ):

        Integer为例:public static int ParseInt(String s);
        Double为例:public static double ParseDouble(String s);
        Boolean为例:public static Boolean ParseBoolean(String s);

但是以上的操作方法形式对于 Character 是不存在的,因为 String 类有一个 charAt() 方法可以取得指定索引的字符。

举例:

//将字符串变为double型数据
public class DoubleDemo
{
	public static void main(String[] args)
	{
		String str = "123.4";	//定义一个字符串
		double x = Double.parseDouble(str);	//将字符串变为 double 型
		System.out.println(x);
	}
}

在将字符串变为数值型数据时需要注意,字符串的组成必须全部由数字组成。

举例:

//将字符串变为boolean型数据
public class BooleanDemo
{
	public static void main(String[] args)
	{
		String str = "true";	//定义一个字符串
		boolean flag = Boolean.parseBoolean(str);	//将字符串转化为boolean型数据
		if (flag) {	//如果条件为真输出相应提示
			System.out.println("条件满足");
		}else {	//如果条件为假输出相应提示
			System.out.println("条件不满足");
		}
	}
}

如果此时的字符串内容不是 true 或 false,那么程序也不会出错,会按照 false 的情况进行处理。

通过以上的操作可以将字符串变为基本数据类型,那么反过来,对于将一个基本类型变为字符串的操作,Java 提供了两种做法。如下:

(1)任何的基本数据类型遇见 String 之后自动变为字符串。

(2)利用 String 类之中提供的一系列 valueOf() 方法完成。

举例( 方式一 ):

//将基本类型变为字符串
public class ToString
{
	public static void main(String[] args)
	{
		int x = 100;
		String str = x + "";	//任何类型与字符串相加之后就是字符串
		System.out.println(str);
	}
}

这种方式必须使用一个字符串,所以一定会产生垃圾,不建议使用。

举例( 方式二 ):

//将基本类型变为字符串
public class ToString
{
	public static void main(String[] args)
	{
		int x = 100;
		String str = String.valueOf(x);	//int变为String
		System.out.println(str);
	}
}

这种做法更方便使用,所以在日后开发中如果遇见基本类型变为 String 的操作建议使用方式二完成。

三、System 类与 Runtime 类

1. System 类

Java 不支持全局方法和变量,Java 设计者将一些系统相关的重要方法和变量收集到了一个统一的类中,这就是 System 类。System 类中的所有成员都是静态的,而要引用这些变量和方法,可直接使用 System 类名作为前缀。之前已使用到了标准输入和输出的 in 和 out 变量,以下介绍 System 类中的几个方法,其他的方法可以参阅 JDK 文档资料。

exit(int status) 方法:提前终止虚拟机的运行。对于发生了异常情况而想终止虚拟机的运行,传递一个非零值作为参数。若在用户正常操作下终止虚拟机的运行,则传递零值作为参数。

CurrentTimeMillis 方法:返回自 1970 年 1 月 1 日 0 点 0 分 0 秒起至今的以毫秒为单位的时间,这是一个 long 类型的大数值。在计算机内部只有数值,没有真正的日期类型及其他各种类型,也就是说,平常用到的日期实质上就是一个数值,但通过这个数值,能够推算出其对应的具体日期时间。

getProperties 方法 :获得当前虚拟机的环境属性。每一个属性都是变量与值以成对的形式出现的。

同理,Java 作为一个虚拟的操作系统,它也有自己的环境属性。Properties 是 Hashtable 的子类,正好可以用于存储环境属性中的多个 “ 变量/值 ” 对格式的数据,getProperties 方法返回值是包含了当前虚拟机的所有环境属性的 Properties 类型的对象。

下面演示打印出当前虚拟机的所有环境属性的变量和值:

//打印当前虚拟机的所有环境属性和变量的值
import java.util.*;
public class Systeminfo
{
	public static void main(String[] args)
	{
		Properties sp = System.getProperties();	//获取当前虚拟机的环境属性
		Enumeration e = sp.propertyNames();	//获取环境属性中所有的变量
		//循环打印出当前虚拟机的所有环境属性的变量和值
		while (e.hasMoreElements()) {
			String key = (String) e.nextElement();
			System.out.println(key + " = " + sp.getProperty(key));
		}
	}
}

2.Runtime 类

在 Java 程序运行时,每一个 JVM 进程之中都会存在唯一的一个 Runtime 类的实例化对象。这个类是一个明显的单例设计模式,此类将构造方法私有化了,既然是单例设计模式,那么一定会在类的内部提供一个 static 定义的方法,用于取得本类的实例化对象。

取得 Runtime 类对象:public static Runtime getRuntime();

取得了 Runtime 类的实例化对象之后,可以利用以下的方法取得一些内存的相关信息。

        最大可用内存数:public long maxMemory();
        总共的可用内存数:public long totalMemory();
        空闲内存数:public long freeMemory();

那么如果在程序之中出现了过多的垃圾,则一定会影响性能,此时可以利用 Runtime 类的如下方法清除垃圾:public void gc()。

举例:

//取得内存值
public class GetMemorySize
{
	public static void main(String[] args)
	{
        //获取正在运行的Runtime对象的引用
		Runtime run = Runtime.getRuntime();	//单例设计
		String str = "";	//定义一个字符串
        //通过循环产生垃圾
		for (int x = 0; x < 5000; x++) {
			str += x;	//垃圾产生
		}
		System.out.println("1.最大可用内存:" + run.maxMemory());
		System.out.println("1.总共可用内存:" + run.totalMemory());
		System.out.println("1.空闲内存:" + run.freeMemory());
		run.gc();    //清除垃圾
		System.out.println("———————————————————————————————");
		System.out.println("2.最大可用内存:" + run.maxMemory());
		System.out.println("2.总共可用内存:" + run.totalMemory());
		System.out.println("2.空闲内存:" + run.freeMemory());
	}
}

四、日期操作类

由于历史上设计的原因,Java 中有关时间的 API 比较混乱,在最早的 java.util.Date 之后,Java 提供了 jdbc 中使用的 java.sql.Date,以及随后增加用于本地化时间的 Calendar 类。解决原先的时间 API 令人迷惑,不够易用的问题,Java 8 中引入了 java.time 包来彻底改变这个让人讨厌的时间 API。需要注意的是新的时间类都是不可改变并且线程安全的。那么现在来看一下如何表示日期、时间。

1.日期类

日期类及其说明如下表所示:

类名 说明
LocalDateTime 存储了日期和时间,如 2014-08-27T14:43:14.539
LocalDate 存储了日期,如 2014-08-25
LocalTime 存储了时间,如 14:43:14.539

上面的类可以由下面的类组合。Year 表示年份,Month 表示月份,YearMonth 表示年月,MonthDay 表示月日,DayOfWeek 存储星期的一天。

举例:

//取得当前的日期时间
import java.time.*;
public class GetDatetime
{
	public static void main(String[] args)
	{
		//新建一个LocalDateTime对象获取当前时间
		LocalDateTime localDateTime = LocalDateTime.now();
		System.out.println(localDateTime);	//直接输出对象
	}
}

此处的输出结果相较于 Java 7 中的 java.util.Date 更加的清晰易懂。符合国人习惯。

Java 8 在 java.util.time 中提供了许多实用方法。如判断是否闰年、同月日关联到另一年份等。

举例:

//判断是否闰年
import java.time.*;
public class LeapYear
{
	public static void main(String[] args)
	{
		//用指定的年获取一个Year
		Year year1 = Year.of(2019);
		//从Year获取YearMonth
		YearMonth yearMonth = year1.atMonth(2);
		//YearMonth指定日期得到LocalDate
		LocalDate localDate2 = yearMonth.atDay(5);
		System.out.println("时间:" + localDate2);
	
		//判断是否是闰年
		System.out.println("是否为闰年:" + localDate2.isLeapYear());
		//自动处理闰年的2月日期
		//创建一个MonthDay
		MonthDay monthDay = MonthDay.of(2, 5);
		LocalDate leapYear = monthDay.atYear(2019);
		System.out.println("闰年:" + leapYear);
		//同一个MonthDay关联到另一个年份上
		LocalDate nonLeapYear = monthDay.atYear(2020);
		System.out.println("非闰年:" + nonLeapYear);
	}
}

Java.time 的 API 提供了大量相关的方法。如下表:

方法 说明
of 静态工厂方法,如:Year.of(2019)
parse 静态工厂方法,关注于解析
get 获取某些东西的值
is 检查某些东西的是否是 true
with 不可变的 setter 等价物
plus 加一些量到某个对象
minus 从某个对象减去一些量
to 转换到另一个类型
at 把这个对象与另一个对象组合起来

2.日期格式化类

在某些情况下,开发者可能要对日期对象进行转换。例如,程序中用的另外一个类的方法要求一个 LocalDate 类型的参数。有时,要将用到 LocalDate 对象表示的日期以指定的格式输出,或将用特定格式显示的日期字符串转换成一个 LocalDate对象,java.time.format 包是专门用来格式化输出时间/日期的。

举例:

//将时间对象格式化为字符串
import java.time.*;
import java.time.format.*;
public class DateFormatDemo
{
	public static void main(String[] args)
	{
		//获取当前时间
		LocalDate localDate = LocalDate.now();
		//指定格式化规则
		DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/uuuu");
		//将当前时间格式化
		String str = localDate.format(f);
		System.out.println("时间:" + str);
	}
}

五、正则表达式

String 是一种功能强大的数据类型,但在进行 String 类的操作之中,除了 String 类本身所具备的若干方法之外,String 也可以利用正则表达式完成一些更为复杂的操作以及验证。

1.正则的引出

举例:

//判断字符串是否由数字组成
public class JudgeString
{
	public static void main(String[] args) throws Exception
	{
		if (isNumber("123")) {	//判断字符串是否有数字组成
			System.out.println("由数字组成");
		}else {
			System.err.println("不是由数字组成");
		}
	}
	public static boolean isNumber(String str)
	{
		char data[] = str.toCharArray();	//将字符串转化成char数组
		for (int x = 0; x < data.length; x++) {	//循环遍历该数组
			if (data[x]<'0' || data[x]>'9') {	//判断数组中的每个元素是否是数字
				return false;
			}
		}
		return true;
	}
}

如果是一些更为复杂的验证,那么按照如上方式所编写的代码肯定更多,所以此时,代码可以简化为如下形式:

//应用正则表达式
public class RegExp
{
	public static void main(String[] args) throws Exception
	{
		if ("123".matches("\\d+")) {	//利用正则表达式
			System.out.println("由数字组成");
		}else {
			System.err.println("不是由数字组成");
		}
	}
}

在程序之中出现的 “ \\d+ ” 实际上就属于正则表达式的概念,我们发现使用正则表达式可以简化我们的程序。在 JDK 1.4 之前,Java 本身是不具备正则的操作支持的,如果需要使用正则,则需要通过 apache 下载一个正则的开发包。而到了 JDK 1.4 之后,Java 开始支持了正则,同时给出了 java.util.regex 开发包,此包提供了正则的操作类,在这个包之中只提供了两个操作类:Pattern、Matcher,可是在一般的开发之中很少去直接使用这两个类。在 JDK 1.4 之后对于 String 类进行了大量的修改,里面增加了与正则有关的操作方法,有如下几个方法是可以支持正则操作的:

方法名称 描述
public Boolean matches(String regex) 将字符串与给出的正则进行匹配验证
public String repalceAll(String regex,String replacement) 按照指定的正则全部替换
public String replaceFirst(String regex,String replacement) 按照指定的正则替换首个
public String[] split(String regex) 按照指定的正则拆分
public String[] split(String regex,int limit) 拆分为指定长度的字符串数组

如果想要操作这些方法,那么就必须首先清楚正则标记。

2.正则标记

在正则操作之中,使用一系列的标记符号是一件非常重要的任务,不光是 Java,只要是支持正则操作的程序,例如,JavaScript 标记都是统一的。所有的标记都在 java.util.regex.Pattern 类提供,下面给出一些核心的正则标记:

(1)字符,表示单个字符,只能出现 1 位。

x:表示是一个指定的一位字符,例如:编写一个 a,表示是字母 a;

\\:表示一位字符 “ \ ”,但是由于 “ \ ” 有个数含义,所以使用 “ \\ ” 表示一位 “ \ ”;

\n:匹配换行;

(2)字符范围,在指定的字符范围之中选 1 位,只能出现 1位。

[abc]:表示可以是 a、b、c 中的任意一位;

[^abc]:表示不是 a、b、c 中的任意一位;

[a-zA-Z]:表示是任意一位字母( 大写或小写 );

[0-9]:表示是任意一位数字。

(3)简洁表达式,表示 1 位。

.:表示任意的一位字符;

\d:表示一位数字,等价于 “ [0-9] ”;

\D:表示一位非数字,等价于 “ [^0-9] ”;

\s:表示一位空格,等价于 “ [\t\n\x0B\f\r] ”;

\S:表示一位非空格,等价于 “ [^\t\n\x0B\f\r] ”;

\w:表示一位字母、数字、_,等价于 “ [a-zA-Z0-9_] ”;

\W:表示一位非字母、数字、_,等价于 “ [^a-zA-Z0-9_] ”;

(4)边界匹配,Java 用不上。

^:表示正则的开头;

$:表示正则的结尾。

(5)数量表示,之前的正则每个符号只表示一位,如果要表示多位,则必须使用以下的数量关系。

正则 ?:表示此正则可以出现 0 次或 1次;

正则 + :表示此正则可以出现 1 次或多次;

正则 * :表示此正则可以出现 0 次、1 次或多次;

正则 {n} :表示此正则出现正好 n 次;

正则 {n,} :表示此正则出现 n 次以上;

正则 {n,m} :表示此正则出现 n ~ m 次。

(6)逻辑操作。

正则 1 正则 2 :正则 1 之后紧跟正则 2 操作;

正则 1 | 正则 2 :表示或的关系,有一套正则标记匹配即可;

( 正则 ):表示按照一组来使用。

3.利用 String 进行正则操作

在 String 类中提供了与正则直接有关的操作方法,下面将使用这些方法进行正则标记的验证。

举例:

//字符串替换
public class SubString
{
	public static void main(String[] args) throws Exception
	{
		String str = "a1b22c333d4444e55555f666666g";
		String regex = "[0-9]+";	//数字出现1次或多次
		//String regex = "\\d+";	//数字出现1次或多次
		System.out.println(str.replaceAll(regex, ""));
	}
}

对于 “ [0-9] ” 的这个标记,实际上也可以使用 “ \\d ” 表示,代码中已注释。

举例:

//验证邮箱格式
public class EmailValidation
{
	public static void main(String[] args) throws Exception
	{
		String str = "[email protected]";
		String regex = "\\w+@\\w+\\.\\w+";
		System.out.println(str.matches(regex));
	}
}

六、Math 与 Random 类

在 Math 类中提供了大量的数学计算方法。Math 类包含了所有用于几何和三角的浮点运算方法,这些方法都是静态的,每个方法的使用都非常简单。

如:四舍五入:public static long round(double a);

round() 是将小数点之后的所有小数位四舍五入,最后只剩下整数部分。

(1)如果参数为正数,且小数点后第一位 >= 5,运算结果为参数的整数部分 +1.

(2)如果参数为负数,且小数点后第一位 >= 5( 小数第一位等于 5,小数位数多于1 ),运算结果为参数的整数部分 -1.

(3)如果参数为正数,且小数点后第一位 <5;或者参数为负数,且小数点后第一位 <=5( 小数只有一位 ),运算结果为参数的整数部分。

        double num = 12.345;
        System.out.println(Math.round(num));    //输出结果为12
        Math.round(15.5) = 16;
        Math.round(-15.5) = 15;
        Math.round(-15.51) = -16;

Random 类是一个随机数产生器,随机数是按照某种算法产生的,一旦用一个初值创建 Random 对象,就可以得到一系列的随机数。但如果用相同的初值创建 Random 对象,得到的随机数序列是相同的,也就是说,在程序中看到的 “ 随机数 ” 是固定的那些数,起不到 “ 随机 ” 的作用。针对这个问题,Java 设计者在 Random 类的 Random() 构造方法中使用当前的时间来初始化 Random 对象,因为没有任何时刻的时间是相同的,所以就可以减少随机数序列相同的可能性。

下面利用 Random 类来产生 5 个 0~100 之间的随机整数:

//利用Random类来产生5个0~100之间的随机整数
import java.util.Random;
public class RandomDemo
{
	public static void main(String[] args) throws Exception
	{
		Random r = new Random();	//新建一个Random对象用于生成随机数
		for (int i = 0; i < 5; i++) {	//循环5次
			System.out.println(r.nextInt(100) + "\t");//输出随机数,并在每个随机数之间加空格
		}
	}
}

利用 Random 随机产生一组数列,这种方式得到的结果事先是未知的。因此在以后编写验证码的时候可以利用此类完成。

七、大数字操作类

现在要对一个非常大的数字进行操作,并且这个数字已经超过了 double 的范畴,我们唯一的做法是将数字变为字符串,之后按位进行手工的计算。但在 Java 里面为了简化此类操作专门提供了两大数字操作类:java.math.BigInteger、java.math.BigDecimal。

1.大型整数操作类 BigInteger

如果数字超过该类型的最大范围,结果会提示 “ Infinity ”。在 BigInteger 类的构造方法( public BigInteger(String val) )里面已经清楚的描述出了,如果数据过大,则只能利用字符串保存,而后在 BigInteger 类之中提供了若干个基本的数学操作。下面看一下 BigInteger 的四则运算:

//BigInteger的四则运算
import java.math.BigInteger;
public class BigNumDemo
{
	public static void main(String[] args) throws Exception
	{
		//定义两个大的整数
		BigInteger bigA = new BigInteger("123456789123456789");
		BigInteger bigB = new BigInteger("1234567");
		//对两个数进行加法操作
		System.out.println("加法操作:" + bigA.add(bigB));
		//对两个数进行减法操作
		System.out.println("减法操作:" + bigA.subtract(bigB));
		//对两个数进行乘法操作
		System.out.println("乘法操作:" + bigA.multiply(bigB));
		//对两个数进行除法操作
		System.out.println("除法操作:" + bigA.divide(bigB));
		//对两个数进行除法操作,并同时保存商与余数
		BigInteger result[] = bigA.divideAndRemainder(bigB);
		System.out.println("商:" + result[0] + ",余数:" + result[1]);
				
	}
}

bigA 除以 BigB 的商与余数保存在 result 数组中,所以可以输出。

2.大型浮点数操作类 BigDecimal

BigDecimal 的实现用到了 BigInteger,不同的是 BigDecimal 加入了小数的概念。一般的 float 型和 Double 型数据只可以用来做科学计算或者是工程计算,由于在商业计算中,要求的数字精度比较高,所以要用到 java.math.BigDecimal 类,它支持任何精度的定点数,可以用它来精确计算货币值。下面给出 BigDecimal 的一些主要方法:

方法名称 描述
add(BigDecimal) BigDecimal 对象中的值相加,然后返回这个对象
subtract(BigDecimal) BigDecimal 对象中的值相减,然后返回这个对象
multiply(BigDecimal) BigDecimal 对象中的值相乘,然后返回这个对象
divide(BigDecimal) BigDecimal 对象中的值相除,然后返回这个对象
toString() 将 BigDecimal 对象的数值转换成字符串
doubleValue() 将 BigDecimal 对象中的值以双精度数返回
floatValue() 将 BigDecimal 对象中的值以单精度数返回
longValue() 将 BigDecimal 对象中的值以长整数返回
intValue() 将 BigDecimal 对象中的值以整数返回

举例:

//BigDecimalDemo的四则运算
import java.math.BigDecimal;
public class CalculateBigDecimal
{
	public static void main(String[] args)
	{
		//定义两个大的整数
		BigDecimal bigA = new BigDecimal("123456789123456789.8");
		BigDecimal bigB = new BigDecimal("1234567.6");
		//对两个数进行加法操作
		System.out.println("加法操作:" + bigA.add(bigB));
		//对两个数进行减法操作
		System.out.println("减法操作:" + bigA.subtract(bigB));
		//对两个数进行乘法操作
		System.out.println("乘法操作:" + bigA.multiply(bigB));
		//对两个数进行除法操作
		System.out.println("除法操作:" + bigA.divide(bigB,BigDecimal.ROUND_DOWN));
		System.out.println("保留一位小数:" + bigA.multiply(bigB).setScale(1,BigDecimal.ROUND_UP));
				
	}
}

ROUND_DOWM 表示舍弃一位,ROUND_UP 表示进一位,ROUND_HALF_UP 表示四舍五入,对于 Math 而言无法实现准确的位数操作,所以处理位数较大的数必须实现精确位的操作用户只有通过 BigDecimal 实现。

八、Integer 类

在 Java 中数据类型分为基本数据类型和复杂数据类型,int 属于基本数据类型,而 Integer 属于后者。

Integer 类在对象中包装了一个基本类型 int 的值。Integer 类型的对象包含一个 int 类型的字段。

此外,该类提供了多个方法,能在 int 类型和 String 类型之间互相转换,还提供了处理 int 类型时非常有用的其他一些常量和方法。

当需要往 ArrayList,HashMap 中放东西时,像 int 这种内建类型是放不进去的,因为容器都是装 object 的,但是 JDK 1.5 引入了自动装箱和自动拆箱,会自动的转化为内建类型的外覆类。

举例:

//Integer类的三种创建方法
public class UseInteger
{
	public static void main(String[] args)
	{
		//使用new关键字新建一个Integer对象并实例化
		Integer num1 = new Integer(100);
		//使用Integer中的方法valueOf创建Integer对象
		Integer num2 = Integer.valueOf(200);
		//利用自动装箱,直接将一个int类型的整数赋给Integer,利用Java的自动装箱进行类型的转化
		Integer num3 = 300;
		System.out.println("三种不同的创建方式:" + num1 + " " + num2 + " " + num3);
	}
}

九、Boolean 类

java.lang.Boolean 类与 Integer 一样是在对象中封装了一个基本布尔型的值。Boolean 类型的对象包含在一个单一的字段中,其类型为布尔值。与 Integer 一样 Boolean 类也有三种生成的方式。此外,Boolean 类中还内置了一些实用的方法。

举例:

//Boolean类的具体使用
public class CompareBoolean
{
	public static void main(String[] args)
	{
		Boolean b1,b2;	//创建两个Boolean型变量b1,b2
		b1 = new Boolean(true);	//给b1赋值
		b2 = new Boolean(false);	//给b2赋值
		int res;	//创建一个整型数res
		res = b1.compareTo(b2);	//比较b1与b2的值
		String str1 = "Both values are equal";
		String str2 = "Object value is true";
		String str3 = "Argument value is true";
		if (res == 0) {
			System.out.println(str1);
		}else if (res > 0) {
			System.out.println(str2);
		}else if (res < 0) {
			System.out.println(str3);
		}
	}
}

十、Byte 类

Byte 类将基本类型 byte 的值包装在一个对象中。一个 Byte 类型的对象只包含一个类型为 byte 的字段。此外该类还为 byte 和 String 的相互转换提供了几种方法,并提供了处理 byte 时非常有用的其他一些常量和方法。

如下表:

方法名称 返回类型 功能说明
byteValue() byte 返回 Byte 类的一个 byte 类型值
compareTo(Byte anotherByte) int 在数值上比较两个类对象,相等返回 0,如果调用对象小于 anotherByte 对象则返回负值,否则返回正值
doubleValue() double 返回 Byte 类的一个 double 类型值
intValue() int 返回 Byte 类的一个 int 类型值
parseByte(String str) byte 将 String 类型转换为 byte 类型
toString() String 返回 Byte 类的一个 String 类型值
equals(Byte anotherByte)   若调用对象值等于 anotherByte 对象的值返回 true,否则返回 false
valueOf(String str | byte x) Byte 对象 返回值为 str 或者 x 的 Byte 对象

举例:

//Byte类的基本使用方法
public class ByteFun
{
	public static void main(String[] args)
	{
		//声明一个byte变量
		byte b = 20;
		
		//返回表示b的一个Byte实例
		Byte b1 = new Byte(b);
		//返回"21"的Byte对象
		Byte b2 = Byte.valueOf("21");
		//返回"22"的Byte对象
		Byte b3 = 22;
		
		//作为一个int型b1值
		int x1 = b1.intValue();
		//作为一个int型b2值
		int x2 = b2.intValue();
		//作为一个int型b3值
		int x3 = b3.intValue();
		
		System.out.println("b1:" + x1 + "b2:" + x2 + "b3:" + x3);
		
		//返回b的String对象
		String str1 = Byte.toString(b);
		//返回b2的String对象
		String str2 = Byte.toString(b2);
		//返回b3的String对象
		String str3 = b3.toString();
		
		System.out.println("str:" + str1 + "str2:" + str2 + "str3:" + str3);
		
		//将String参数解析为有符号的十进制byte
		byte bb = Byte.parseByte("23");
		
		System.out.println("Byte.parseByte(\"23\"):" + bb);
		
		//将b1与b2比较
		boolean bool1 = b1.equals(b2);
		//将b1与b3比较
		boolean bool2 = b1.equals(b3);
		
		System.out.println("b1.equals(b2):" + bool1 + "b1.equals(b3)" + bool2);
	}
}

十一、本文注意事项

1.包装类型不能够随便使用关系运算符比较大小

下面以 Integer 为例针对三种创建对象的方法进行说明。

首先,对于 new 关键字创建的包装类对象,两次 new 得到的对象引用地址是不同的,不能使用 “ == ” 关键字做大小比较。而使用 “ < ” 和 “ > ” 等运算符时,包装类型会调用 valueOf 方法,将运算符两边的对象都转换为基本类型后再做比较。这就是为何 “ == ” 不能使用而 “ < ”、“ > ”、“ <= ”、“ >= ” 这几个符号可以使用的原因。

其次,使用 valueOf 方法创建的 Integer 对象,使用 “ == ” 符号时,运行结果有时候正确,有时候不正确。查看 valueOf 方法的源码,如下:

public static Integer valueOf(int i)
{
	if(i >= -128 && i <= IntegerCache.high)
		return IntegerCache.cache[i + 128];
	else
		return new Integer(i);
}

通过看源代码能够知道,整数类型在 -128 ~ 127 之间时,会使用缓存,如果已经创建了一个相同的整数,使用 valueOf 创建第二次时,不会使用 new 关键字,而用已经缓存的对象。所以使用 valueOf 方法创建两次对象,若对应的数值相同,且数值在 -128 ~ 127 之间时,两个对象都指向同一个地址。

最后,使用 Integer i = 400 这样的方式来创建 Integer 对象,与 valueOf 方法的效果是一样的。

总之,包装类对象不可使用 “ == ” 符做比较运算,如果要进行比较运算时,最好使用 java 类库中的 compareTo 方法。

你可能感兴趣的:(Java)