【小家java】聊聊Java中的System类

简介: 【小家java】聊聊Java中的System类

Java程序在不同操作系统上运行时,可能需要取得平台相关的属性,或者调用平台命令来完成特点功能。Java提供了System类和Runtime类来与程序的运行平台进行交互。


本文讲述System类,需要了解Runtime类的,前往:【小家java】聊聊Java中的Runtime类


主要API


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


我们看看我们偶尔会用到的关于GC的方法:


public static void exit(int status) {
        Runtime.getRuntime().exit(status);
    }
 public static void gc() {
        Runtime.getRuntime().gc();
    }


还有load、loadLibrary、runFinalization、runFinalizersOnExit等方法,无一例外底层都是调用Runtime类的方法,所以此处不再鳌诉了。


获取环境变量和属性值的方法


一个例子,说明一切:


  public static void main(String[] args) {
        //系统环境变量  (注意不是JVM的参数哦)  比如配置的JAVA_HOME等等值
        Map<String, String> envMap = System.getenv();
        //获取JVM的启动参数们:
        //比如托是通过如下方式启动:通过java -jar test.jar -Denv=123启动时指定的值
        Properties properties = System.getProperties(); //获取所有的参数
        System.out.println(properties.getProperty("env")); //123
        //启动参数:的获取(用得很少  注意和上面的区别)
        //比如启动方式为  java -jar test.jar --env=123  这该参数就在main方法的args里
        System.out.println(args);
    }


备注:我发现getenv这个方法没有遵循驼峰命名规范,怪别扭的。


比如JDK中的Hashtable类,也是一个命名不规范的例子。


下面这些属性值,都可以通过System.getProperty("")来获取


image.png


获取系统当前时间方法


currentTimeMillis()和nanoTime()

其实大家都用得非常的多了,获取当前时间特别有效。特别是currentTimeMillis。


  public static void main(String[] args) {
        System.out.println(System.currentTimeMillis());
        System.out.println(System.nanoTime());
        //1534776548329
        //45386393379944
    }


我们发现他俩的值只相差了一位数。所以一定要注意nanoTime返回的并不是纳秒,并不是纳秒,并不是纳秒。其实它的单位叫毫微秒,只是更加的精准些。所以JDK上有说:


System.nanoTime提供相对精确的计时,但是不能用他来计算当前日期。此方法提供毫微秒的精度,但不是必要的毫微秒的准确度。它对于值的更改频率没有作出保证。


所以我们可以用它了计算差值,但千万不要拿来作为时间。它是JDK1.5才提供的


System.currentTimeMillis返回的是从1970.1.1 UTC 零点开始到现在的时间,精确到毫秒,平时我们可以根据System.currentTimeMillis来计算当前日期,星期几等,可以方便的与Date进行转换


标准输入、输出方法


System类的in、out、err分别代表系统的标准输入(通常是键盘)、标准输出(通常是显示器)和错误输出流,并提供了setIn()、setOut()、setErr()方法来改变系统的标准输入、标准输出和标准错误输出流


setOut()方法可以改变输出流

   public static void main(String[] args) throws Exception {
        PrintStream out = System.out; //先把标准的输出缓存到变量
        PrintStream ps = new PrintStream("log.txt");
        System.setOut(ps);
        int age = 11;
        System.out.println("年龄变量成功定义,初始值为11");
        String sex = "女";
        System.out.println("年龄变量成功定义,初始值为女");
        //切换成标准输出
        System.setOut(out);
        System.out.println("程序运行完毕,请查看日志");
    }


结果如下:log.txt文件有如下内容:


image.png


控制台输出:程序运行完毕,请查看日志


  • 那么setIn()是不是可以改变输入流呢?


 public static void main(String[] args) throws Exception {
        InputStream in = System.in; //缓存标准输入
        InputStream ps = new FileInputStream("log.txt");
        System.setIn(ps);
        Scanner scanner = new Scanner(System.in);
        String line = "";
        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            System.out.println(line);
        }
    }


我们发现,标准的输入并不需要我们手动录入了。而是可以直接从文件中读取了,非常的支持定制化需求。


identityHashCode方法、lineSeparator方法、arraycopy方法



说identityHashCode,我们不得不提一个对象的hashCode,因此做如下总结:

一个对象的hashCode和identityHashCode 的关系:


1.对象的hashCode,一般是通过将该对象的内部地址转换成一个整数来实现的


2.当一个类没有重写Object类的hashCode()方法时,它的hashCode和identityHashCode是一致的


3.当一个类重写了Object类的hashCode()方法时,它的hashCode则有重写的实现逻辑决定,此时的hashCode值一般就不再和对象本身的内部地址有相应的哈希关系了


4.当null调用hashCode方法时,会抛出空指针异常,但是调用System.identityHashCode(null)方法时能正常的返回0这个值


5.一个对象的identityHashCode能够始终和该对象的内部地址有一个相对应的关系,从这个角度来讲,它可以用于代表对象的引用地址,所以,在理解==这个操作运算符的时候是比较有用的


所以即使我们重写了hashCode,每个对象的identityHashCode值也会是唯一的。


lineSeparator的使用


换行符。该方法主要解决window系统、linux系统等对换行符定义不一样的问题。之前我们都是这么用:System.getProperty(“line.separator”)。但JDK7为我们提供了一个更为简便的方法:System.lineSeparator()


备注:其实System.lineSeparator()内部调用的还是System.getProperty(“line.separator”)方法。只是使用起来更加方便了

arraycopy方法的使用


显然,又是一个没有遵循驼峰命名的方法名。它是个native方法,所以效率可想而知。因此我们数组拷贝的时候,推荐使用此方法


它可以实现将一个数组的指定个数元素复制到另一个数组中


例如:arraycopy( arr1, 3, arr2, 2, 2);

意思为:将arr1数组里从索引为2的元素开始, 复制到数组arr2里的索引为5的位置, 复制的元素个数为10个.


  public static void main(String[] args) throws Exception {
        Integer[] arr1 = {1, 2, 3, 4, 5};
        Integer[] arr2 = new Integer[5];
        System.arraycopy(arr1, 3, arr2, 2, 3);
        System.out.println(Arrays.toString(arr2)); //[null, null, 4, 5, null]
    }


备注:此处需要注意,任意一个数组的长度被超出范围了,都会抛出异常的:

   public static void main(String[] args) throws Exception {
        Integer[] arr1 = {1, 2, 3, 4, 5};
        Integer[] arr2 = new Integer[5];
        System.arraycopy(arr1, 3, arr2, 2, 5);
        System.out.println(Arrays.toString(arr2)); 
    }
抛出异常:java.lang.ArrayIndexOutOfBoundsException


很显然数组arr1的长度就不足3+5,所以就抛出异常了。同样的如果arr2长度不够,也是一样的结果。所以用的最多的,就是同长度的数组拷贝。


相关文章
|
29天前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
38 6
|
17天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
40 17
|
8天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
12天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
53 4
|
13天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
31 2
|
17天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
21天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
21天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
|
21天前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
23 3
|
24天前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
22 5