System、Runtime、BigDecimal类

System类代表当前Java程序的运行平台,程序不能创建System类的对象,System类提供了一些类变量和类方法,允许直接通过System类来调用这些类变量和类方法。

System类提供了代表标准输入、标准输出和错误输出的类变量,并提供了一些静态方法用于访问环境变量、系统属性的方法,还提供了加载文件和动态链接库的方法;

public class TestSystem
{
	public static void main(String[] args) throws Exception
	{
		//获取系统所有的环境变量
		Map<String,String> env = System.getenv();
		for (String name : env.keySet())
		{
			System.out.println(name + " ------> " + env.get(name));
		}
		//获取指定环境变量的值
		System.out.println(System.getenv("JAVA_HOME"));
		//获取所有的系统属性
		Properties props = System.getProperties();
		//将所有系统属性保存到props.txt文件中
		props.store(new FileOutputStream("props.txt") , "System Properties");
		//输出特定的系统属性
		System.out.println(System.getProperty("os.name"));
	}
}

程序运行后会在当前路径下生成一个props.txt文件,该文件中记录了当前平台的所有系统属性;

System类提供了通知系统进行垃圾回收的gc()方法,以及通知系统进行资源清理的runFinalization()方法;

除此之外,System类的in、out和err分别代表系统的标准输入、标准输出和错误输出流,并提供了setIn()、setOut()和setErr()方法来改变系统的标准输入、标准输出和标准错误输出流;

System类还提供了一个identityHashCode(Object x)方法,该方法返回指定对象的精确hashCode值,也就是根据该对象的地址计算得到的hashCode值。当某个类的hashCode()方法被重写后,该类实例的hashCode()方法就不能唯一地标识该对象;但通过identityHashCode()方法返回的hashCode值,依然是根据该对象的地址计算得到的hashCode值。所以,如果两个对象的identityHashCode值相同,则两个对象绝对是同一个对象;

public class TestIdentityHashCode
{
	public static void main(String[] args) 
	{
		//下面程序中s1和s2是两个不同对象
		String s1 = new String("Hello");
		String s2 = new String("Hello");
		//String重写了hashCode方法——改为根据字符序列计算hashCode值,
		//因为s1和s2的字符序列相同,所以它们的hashCode方法返回值相同
		System.out.println(s1.hashCode() + "----" + s2.hashCode());
		//s1和s2是不同的字符串对象,所以它们的identityHashCode值不同
		System.out.println(System.identityHashCode(s1) + "----" + 
			System.identityHashCode(s2));
		String s3 = "Java";
		String s4 = "Java";
		//s3和s4是相同的字符串对象,所以它们的identityHashCode值相同
		System.out.println(System.identityHashCode(s3) + "----" + 
			System.identityHashCode(s4));
	}
}
//输出
69609650----69609650
366712642----1829164700
2018699554----2018699554

identityHashCode值可以唯一标识该对象,因为identityHashCode值是根据对象的地址计算得到的;

Runtime类

Runtime类代表Java程序的运行时环境,每个Java程序都有一个与之对应的Runtime实例。应用程序不能创建自己的Runtime实例,但可以通过getRuntime()方法获取与之关联的Runtime对象;

Runtime类代表Java程序的运行时环境,可以访问JVM的相关信息,如处理器数量、内存信息等;

public class TestRuntime
{
	public static void main(String[] args) 
	{
		Runtime rt = Runtime.getRuntime();
		System.out.println("处理器数量:" + rt.availableProcessors());
		System.out.println("空闲内存数:" + rt.freeMemory());
		System.out.println("总内存数:" + rt.totalMemory());
		System.out.println("可用最大内存数:" + rt.maxMemory());
	}
}
//输出
处理器数量:4
空闲内存数:126248328
总内存数:128974848
可用最大内存数:1883242496

除此之外,Runtime类还有一个功能------它可以直接单独启动一个进程来运行操作系统的命令:

public class TestExec
{
	public static void main(String[] args)throws Exception
	{
		Runtime rt = Runtime.getRuntime();
		//运行记事本程序
		rt.exec("notepad.exe");
	}
}

Runtime类提供了一系列exec()方法来运行操作系统命令;

BigDecimal类

float、double两种基本浮点类型容易引起精度丢失,例如:

public class TestDouble
{
    public static void main(String args[])
	{
        System.out.println("0.05 + 0.01 = " + (0.05 + 0.01));
        System.out.println("1.0 - 0.42 = " + (1.0 - 0.42));
        System.out.println("4.015 * 100 = " + (4.015 * 100));
        System.out.println("123.3 / 100 = " + (123.3 / 100));
    }
}
//输出
0.05 + 0.01 = 0.060000000000000005
1.0 - 0.42 = 0.5800000000000001
4.015 * 100 = 401.49999999999994
123.3 / 100 = 1.2329999999999999

运行结果表明,Java的double类型会发生精度丢失,尤其在进行算术运算时更容易发生;

为了能精确表示、计算浮点数,Java提供了BigDecimal类。

查看BigDecimal类的BigDecimal(double val)构造器的详细说明时,可以看到不推荐使用该构造器的说明,主要是因为使用该构造器时有一定的不可预知性。当程序使用BigDecimal(0.1)来创建一个BigDecimal对象时,它的值并不是0.1,它实际上等于一个近似0.1的数。这是因为0.1无法准确地表示为double浮点数,所以传入BigDecimal构造器的值不会正好等于0.1(虽然表面上等于该值)。

如果使用BigDecimal(String val)构造器的结果是可预知的----写入new BigDecimal(“0.1”)将创建一个BigDecimal,它正好等于预期的0.1。因此建议优先使用基于String的构造器;

如果必须使用double浮点数作为BigDecimal构造器的参数时,不要直接将该double浮点数作为构造器参数创建BigDecimal对象,而是应该通过BigDecimal.valueOf(double value)静态方法来创建BigDecimal对象;

BigDecimal类提供了add()、subtract()、multiply()、divide()、pow()等方法对精确浮点数进程常规算术运算:

public class TestBigDecimal
{
	public static void main(String[] args) 
	{
		BigDecimal f1 = new BigDecimal("0.05");
		BigDecimal f2 = BigDecimal.valueOf(0.01);
		BigDecimal f3 = new BigDecimal(0.05);
		System.out.println("下面使用String作为BigDecimal构造器参数的计算结果:");
		System.out.println("0.05 + 0.01 = " + f1.add(f2));
		System.out.println("0.05 - 0.01 = " + f1.subtract(f2));
		System.out.println("0.05 * 0.01 = " + f1.multiply(f2));
		System.out.println("0.05 / 0.01 = " + f1.divide(f2));
		System.out.println("下面使用double作为BigDecimal构造器参数的计算结果:");
		System.out.println("0.05 + 0.01 = " + f3.add(f2));
		System.out.println("0.05 - 0.01 = " + f3.subtract(f2));
		System.out.println("0.05 * 0.01 = " + f3.multiply(f2));
		System.out.println("0.05 / 0.01 = " + f3.divide(f2));
	}
}
//输出
下面使用String作为BigDecimal构造器参数的计算结果:
0.05 + 0.01 = 0.06
0.05 - 0.01 = 0.04
0.05 * 0.01 = 0.0005
0.05 / 0.01 = 5
下面使用double作为BigDecimal构造器参数的计算结果:
0.05 + 0.01 = 0.06000000000000000277555756156289135105907917022705078125
0.05 - 0.01 = 0.04000000000000000277555756156289135105907917022705078125
0.05 * 0.01 = 0.0005000000000000000277555756156289135105907917022705078125
0.05 / 0.01 = 5.000000000000000277555756156289135105907917022705078125

书籍:疯狂Java讲义
学习所做的笔记,特此记录下来

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/84029467
今日推荐