首页 > 编程语言 >JTCR-探索 java.lang-16

JTCR-探索 java.lang-16

时间:2024-04-23 14:33:18浏览次数:36  
标签:lang JTCR java System 线程 println new 方法 out

原始类型包装器

为了在必须使用类类型的地方使用原始类型,每个原始类型都有一个包装器,该包装器将原始类型封装成类类型。

抽象类 Number 作为所有数值类型包装类的父类,定义了返回不同类型值的抽象方法。它的子类有 Byte、Short、Integer、Long、Float 和 Double。这些抽象方法形式为

// xx 表示上述 6 种数值类型的任意一种
xx xxValue();

这些方法返回的值可能是截断或舍入后的,取决于包装类中值的具体大小和调用的方法。

Float 和 Double 定义的常量如下

名称 说明
BYTES float 或 double 以字节为单位的长度
MAX_EXPONENT 最大指数
MAX_VALUE 最大正数
MIN_EXPONENT 最小指数
MIN_NORMAL 最小正 normal 值
MIN_VALUE 最小正数
NaN 不是数
POSITIVE_INFINITY 正无穷
NEGATIVE_INFINITY 负无穷
SIZE 包装值的位宽
TYPE float 或 double 的 Class 对象

最小正数和最小正 normal 值的区别在于,最小正数的 binary point(二进制小数点)前面是 0,而最小正 normal 值的 binary point 前面是 1。

Float 和 Double 提供了 isInfinite() 方法,当值无限大或无限小时,返回 true;否则返回 false。提供的 isNaN() 方法,当值不是数时,返回 true;否则返回 false。

从 JDK9 开始,所有数值类型包装器的接收原始类型和字符串的构造器废弃,使用 valueOf() 方法代替。

整型类型包装器提供将字符串转换成对应原始类型的方法。

// XX 表示 Byte/Short/Integer/Long 其中的一个
XX.parseXX(String);

所有整型类型包装器的 toString() 方法将值转换成字符串。Integer 和 Long 提供了 toBinaryString()toOctalString()toHexString() 方法将值转换成以二进制、八进制和十六进制表示的字符串形式。

Character 类提供的 charValue() 方法返回 char 值。定义有如下常量

名称 说明
BYTES char 以字节为单位的长度
MAX_RADIX 最大基数
MIN_RADIX 最小基数
MAX_VALUE 最大字符值
MIN_VALUE 最小字符值
TYPE char 的 Class 对象

Character 的 static char forDigit(int num, int radix) 方法返回整数对应的字符。

static int digit(char digit, int radix) 方法返回字符对应的整数。

int compareTo(Character c) 方法比较两个字符的大小。

getDirectionality() 方法确定字符的方向,方向由预定义的常量表示。

Character.Subset 类用于描述 Unicode 的子集;Character.UnicodeBlock 包含 Unicode 字符块。

最开始,Unicode 字符占 16 位,与 char 大小相同,范围为 0 ~ FFFF。随着 Unicode 字符集的扩充,字符范围扩展到了 0 ~ 10FFFF。字符不再仅用 16 位就可以表示了。从 JDK5 开始,Character 类就支持 32 位字符。

码点(code point)表示 Unicode 字符对应的数值,范围为 0 ~ 10FFFF。值大于 FFFF 的字符称为补充字符(supplemental characters),0 ~ FFFF 的字符称为基本多平面(basic multilingual plane, BMP)。对于补充字符,Java 使用两种方式处理。其中一种为,使用 2 个 char 表示一个字符,第一个 char 称为高代理项(high surrogate),第二个 char 称为低代理项(low surrogate)。另一种方法为,将已存在的部分方法参数类型从 char 改为 int。

Boolean 主要用于 boolean 值需要作为引用传递的情况。构造时,仅当传入的字符为大写或小写的 true 时为 true,否则为 false。Boolean 的 TYPE 表示 boolean 的 Class 对象。

Void

Void 类有名为 TYPE 的常量,引用 void 的 Class 对象。Void 类不能实例化。

Process

Process 抽象类封装了一个进程,它是 Runtime 类的 exec() 方法和 ProcessBuilder 类的 start() 方法返回的对象类型的超类。JDK9 开始,ProcessHandle 对象可以用于处理进程,ProcessHandle.Info 对象可以获取进程相关的信息。ProcessHandle.Info 对象的 totalCpuDuration() 方法返回进程使用的 CPU 时间量,ProcessHandle 类的 isAlive() 方法根据当前进程是否正在执行返回 true 或 false。

Runtime

Runtime 类封装了 Java 运行时环境,不能实例化。Runtime.getRuntime() 方法返回当前 Runtime 对象,调用该对象提供的方法可以控制 JVM 的状态和行为。

totalMemory() 方法返回对象堆(object heap)的大小,freeMemory() 方法返回对象堆的剩余容量大小。gc() 方法调用垃圾回收器。

public static void m() {
  var r = Runtime.getRuntime();
  System.out.println(r.totalMemory());
  System.out.println(r.freeMemory());
  String s = "abc";
  System.out.println(r.freeMemory());
  r.gc();
  System.out.println(r.freeMemory());
}

exec() 方法有多种形式,其中一种形式是接收一个将运行的程序名称和调用该程序需要的输入参数。返回 Process 对象。exec() 方法的实现依赖于具体的 OS。Process 对象的 destroy() 方法终止子进程;waitFor() 方法使得当前线程等待,直到 Process 表示的子进程终止;exitValue() 方法返回子进程完成时返回的值。子进程运行时,可以读写标准输入输出,调用 getInputStream()getOutputStream() 方法获取。

public static void m() {
  var r = Runtime.getRuntime();
  Process p = r.exec("notepad");
  p.waitFor();
  System.out.println(p.exitValue());
}

Runtime.Version

Runtime.version() 方法返回表示当前平台的 Runtime.Version 对象,它封装了 Java 环境的版本信息,JDK9 引入。

版本信息的前 4 个元素指定了版本号,分别为特性(feature)版本号、临时(interim)版本号、更新版本号和补丁版本号。特性版本号指定了 JDK 的发行版本,从 10 开始;临时版本号出现在两个发行版本之间、更新版本号表示处理安全和其他问题、补丁版本号表示处理紧急问题。后面的元素是可选的。

JDK10 开始,Runtime.Version 引入了下面 4 个方法获取对应类型的版本号

  • int feature()
  • int interim()
  • int update()
  • int patch()
public static void m() {
  Runtime.Version v = Runtime.verion();
  System.out.println(v.feature());
  System.out.println(v.interim());
  System.out.println(v.update());
  System.out.println(v.patch());
}

Runtime.Version 对象的 build() 方法返回构建号;pre() 方法返回预发行信息;Optional<String> optional() 方法返回其他版本信息;compareTo(Runtime.Version obj)compareToIgnoreOptional(Runtime.Version obj) 方法比较版本;equals(Object obj)equalsIgnoreOptional(Object obj) 方法比较版本是否相等。List<Integer> version() 方法将版本信息以列表的方式返回;parse(String) 方法接收一个有效版本形式的字符串,将其转换为 Runtime.Version 对象。

ProcessBuilder

ProcessBuilder 类提供了另一种创建和管理进程的方式。

ProcessBuilder(List<String> args);
ProcessBuilder(String... args);

上述的构造器中,第一个参数为程序名,后续的参数为启动程序时指定的命令行参数。

ProcessBuilder 类的部分方法返回 ProcessBuilder.Redirect 抽象类,它封装了和父进程关联的 I/O 源和 target。ProcessBuilder.Redirect 的 to() 方法重定向 I/O target,from() 方法重定向 I/O 源,appendTo() 方法添加文件,file() 方法返回关联的文件对象。

  • static ProcessBuilder.Redirect to(File f)
  • static ProcessBuilder.Redirect from(File f)
  • static ProcessBuilder.Redirect appendTo(File f)
  • File file()
public static void m() {
  var p = new ProcessBuilder("notepad.exe", "inputtext");
  p.start();
}

System

System 类有很多静态变量和方法。其中,静态变量 in 表示运行时的标准输入、out 表示运行时的标准输出、err 表示运行时的标准错误输出。currentTimeMillis() 获得从 1970 年开始到当前为止以毫秒为单位流逝的时间。nanoTime() 则获得以纳秒为单位的时间。

public class Elapsed {
    // 循环的时间开销为:0 ms
    // 循环的时间开销为:1811200 ns
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        long naStart = System.nanoTime();
        for (int i = 0; i < 1_000_000_000; i++) {
            int a = 1 + 1;
        }
        long end = System.currentTimeMillis();
        long naEnd = System.nanoTime();
        System.out.println("循环的时间开销为:" + (end - start) + " ms");
        System.out.println("循环的时间开销为:" + (naEnd - naStart) + " ns");
    }
}

arraycopy() 方法用于将一个数组中指定位置开始的元素复制到另一个数组中指定位置。

public class ACDemo {
    // a: abcde
    // b: mnopq
    // a: abcde
    // b: abcde
    // a: cdede
    public static void main(String[] args) {
        char[] a = {'a', 'b', 'c', 'd', 'e'};
        char[] b = {'m', 'n', 'o', 'p', 'q'};
        System.out.println("a: " + new String(a));
        System.out.println("b: " + new String(b));
        System.arraycopy(a, 0, b, 0, a.length);
        System.out.println("a: " + new String(a));
        System.out.println("b: " + new String(b));
        // 同一个数组可以作为源数组和目标数组
        System.arraycopy(a, 2, a, 0, a.length - 2);
        System.out.println("a: " + new String(a));
    }
}

Object

Object 类的 clone() 方法用于浅复制实现了 Cloneable 接口的类对象。复制之后,如果类中有类类型的成员,则两个对象引用相同的成员对象。打开 I/O 流的对象执行浅复制后会导致两个对象都可以操作打开的流。

Class

Class 对象封装了类或接口的运行时状态,它在类加载时自动创建,不能显式定义 Class 对象。形式为

// T 表示与 Class 对象关联的类或接口的类型
class Class<T>;
public class RTTI {
    static class X {
        int a;
    }

    static class Y extends X {
        double b;
    }

    // x 的类型为:a.b.RTTI$X
    // y 的类型为:a.b.RTTI$Y
    // y 的超类类型为:a.b.RTTI$X
    public static void main(String[] args) {
        X x = new X();
        Y y = new Y();
        Class<? extends X> aClass = x.getClass();
        System.out.println("x 的类型为:" + aClass.getName());
        aClass = y.getClass();
        System.out.println("y 的类型为:" + aClass.getName());
        System.out.println("y 的超类类型为:" + aClass.getSuperclass().getName());
    }
}

ThreadGroup

ThreadGroup 创建一组线程。构造器如下

// 当前线程作为创建的线程组的父线程,线程组名称由 gN 指定
ThreadGroup(String gN);

// 创建的线程组的父线程由 p 指定,线程组名称由 gN 指定
ThreadGroup(ThreadGroup p, String gN);

ThreadGroup 提供了将一组线程作为一个整体管理的方式。

public class ThreadGroupDemo {
    static class NewThread extends Thread {
        boolean suspend;

        NewThread(String name, ThreadGroup g) {
            super(g, name);
            suspend = false;
        }

        public void run() {
            for (int i = 5; i > 0; i--) {
                try {
                    Thread.sleep(1000);
                    System.out.println(getName() + " 执行 " + i);
                    synchronized (this) {
                        while (suspend) {
                            wait();
                        }
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(getName() + " 退出");
        }

        synchronized void suspendMethod() {
            suspend = true;
        }

        synchronized void resumeMethod() {
            suspend = false;
            notify();
        }
    }
//java.lang.ThreadGroup[name=a,maxpri=10]
//    Thread[a1,5,a]
//    Thread[a2,5,a]
//
//java.lang.ThreadGroup[name=b,maxpri=10]
//    Thread[b1,5,b]
//    Thread[b2,5,b]
//
//线程组 a 等待(此时,线程组 a 等待,但修改前的执行无法阻止,如下面 a1 和 a2 执行了 1 次)
//a1 执行 5
//b2 执行 5
//a2 执行 5
//b1 执行 5
//b2 执行 4
//b1 执行 4
//b2 执行 3
//b1 执行 3
//线程组 a 恢复执行
//等待线程完成
//b2 执行 2
//b1 执行 2
//a1 执行 4
//a2 执行 4
//b2 执行 1
//b1 执行 1
//b1 退出
//b2 退出
//a2 执行 3
//a1 执行 3
//a2 执行 2
//a1 执行 2
//a1 执行 1
//a1 退出
//a2 执行 1
//a2 退出
    public static void main(String[] args) {
        ThreadGroup a = new ThreadGroup("a");
        ThreadGroup b = new ThreadGroup("b");
        // 将线程分组
        NewThread a1 = new NewThread("a1", a);
        NewThread a2 = new NewThread("a2", a);
        NewThread b1 = new NewThread("b1", b);
        NewThread b2 = new NewThread("b2", b);

        // 加上当前线程,5 个线程同时执行
        a1.start();
        a2.start();
        b1.start();
        b2.start();

        // 输出线程组的信息
        a.list();
        System.out.println();
        b.list();
        System.out.println();

        Thread[] threads = new Thread[a.activeCount()];
        a.enumerate(threads);
        // 暂停线程组 a 的所有线程
        for (Thread t : threads) {
            ((NewThread)t).suspendMethod();
        }
        System.out.println("线程组 a 等待");
        try {
            // 当前线程休眠
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println("线程组 a 恢复执行");
        // 恢复线程组 a 的所有线程
        for (Thread t : threads) {
            ((NewThread)t).resumeMethod();
        }
        System.out.println("等待线程完成");
        try {
            // 等待线程执行完成
            a1.join();
            a2.join();
            b1.join();
            b2.join();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

参考

[1] Herbert Schildt, Java The Complete Reference 11th, 2019.
[2] difference-between-javas-double-min-normal-and-double-min-value
[3] double-min-value-vs-double-min-normal
[4] What-is-a-binary-point
[5] https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html
[6] https://docs.oracle.com/javase/9/docs/api/java/lang/Runtime.Version.html
[7] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessBuilder.html
[8] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessBuilder.Redirect.html
[9] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ProcessBuilder.Redirect.Type.html

标签:lang,JTCR,java,System,线程,println,new,方法,out
From: https://www.cnblogs.com/xdreamc/p/17495241.html

相关文章

  • HIVE使用java生成自定义(UDF)函数,并在hive命令中使用
      创建一个maven项目(不要用springboot)  引入依赖<!--添加hive依赖--><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>3.1.1</versio......
  • JavaScript注释:单行注释和多行注释详解
    为了提高代码的可读性,JS与CSS一样,也提供了注释功能。JS中的注释主要有两种,分别是单行注释和多行注释。在编程的世界里,注释是那些默默无闻的英雄,它们静静地站在代码的背后,为后来的维护者、为未来的自己,甚至是为那些偶然间翻阅你代码的开发者提供着不可或缺的信息。今天,我们就来深......
  • Cassandra节点重启失败 java.lang.RuntimeException: A node with address *** alread
    问题杀死一个节点后重启报节点已存在:java.lang.RuntimeException:Anodewithaddress***alreadyexists,cancellingjoin.Usecassandra.replace_addressifyouwanttoreplacethisnode.解决方法到另一个节点Cassandra的bin目录./nodetoolstatus查看需要重启......
  • fastjson导致的程序崩溃:A fatal error has been detected by the Java Runtime Enviro
    ##AfatalerrorhasbeendetectedbytheJavaRuntimeEnvironment:##EXCEPTION_ACCESS_VIOLATION(0xc0000005)atpc=0x000001da4d3ab6b3,pid=15996,tid=0x0000000000006478##JREversion:Java(TM)SERuntimeEnvironment(8.0_361)(build1.8.0_361-b09)......
  • Java中的static关键字解析
    一.static关键字的用途二.static关键字的误区三.常见的笔试面试题一.static关键字的用途在《Java编程思想》P86页有这样一段话:“static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,......
  • 认识一下JavaScrip中的元编程
    本文分享自华为云社区《元编程,使代码更具描述性、表达性和灵活性》,作者:叶一一。背景去年下半年,我在微信书架里加入了许多技术书籍,各种类别的都有,断断续续的读了一部分。没有计划的阅读,收效甚微。新年伊始,我准备尝试一下其他方式,比如阅读周。每月抽出1~2个非连续周,完整阅读一......
  • Java switch() case中的switch可用的数据类型 byte,shor,int ,string ,char不能是long
    Javaswitch()case中的switch可用的数据类型   byte,shor,int,string,char1.swtich()里面必须是int和enum--即枚举类型。2.short、char或者byte他会自动转换为int的。。3.long不能自动转换为int,因为long比int范围大..可能会丢失精度..4.java把string也'转化'成int了,用......
  • javascript入门
    目录javascript入门js简介与导入方式导入方式js基本语法变量数据类型条件语句循环语句函数事件DOM操作javascript入门ps:本篇章只介绍js语言最基本的使用,是偏向入门的文档,想要熟练掌握js还是需要多读其他技术文档js简介与导入方式首先javascript与java没有任何关系!Jav......
  • Java泛型如何对属性操作
    对于多个类型相似的操作,如何实现统一处理,简化操作。例如,现在由多个类定义,类定义中都包含客户编号,但是缺少客户名称。如果采用常规的方式,我对于需要展示客户名称的场景,需要对每个类的每个场景去处理,来根据客户编号获取客户信息,并设置客户名称。但是这种方式对存在很多的冗余代码......
  • 拥抱 invokedynamic,在 Java agent 中驯服类加载器
    前言在开发项目的agent时,找了很多类隔离加载的解决方案,最终参照开源项目实现,采用了ElasticAPMJavaagent的方案。以下为本方案的核心说明文章。翻译正文ByteBuddy最棒的一点是,它允许您编写Javaagent,而无需手动处理字节代码。agent作者只需用纯Java编写要注入的代码,......