zoukankan      html  css  js  c++  java
  • Java基础类库

    Java基础类库

    使用Scanner获得键盘输入:

    public class ScannerKeyBoardTest
    {
        public static void main(String[] args)
        {
            // System.in代表标准输入,就是键盘输入
            Scanner sc = new Scanner(System.in);
            // 增加下面一行将只把回车作为分隔符
            // sc.useDelimiter("
    ");
            // 判断是否还有下一个输入项
            while(sc.hasNext())
            {
                // 输出输入项
                System.out.println("键盘输入的内容是:"
                    + sc.next());
            }
        }
    }

    读取文件内容:

    public class ScannerFileTest
    {
        public static void main(String[] args)
            throws Exception
        {
            // 将一个File对象作为Scanner的构造器参数,Scanner读取文件内容
            Scanner sc = new Scanner(new File("ScannerFileTest.java"));
            System.out.println("ScannerFileTest.java文件内容如下:");
            // 判断是否还有下一行
            while(sc.hasNextLine())
            {
                // 输出文件中的下一行
                System.out.println(sc.nextLine());
            }
        }
    }

    System类:

    通过System类访问操作的环境变量和系统属性:

    public class SystemTest
    {
        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"));
        }
    }

    通过 identityHashCode 判断是否同一个对象:

    public class IdentityHashCodeTest
    {
        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));
        }
    }

    Runtime类代表java程序运行时环境:

    public class RuntimeTest
    {
        public static void main(String[] args)
        {
            // 获取Java程序关联的运行时对象
            Runtime rt = Runtime.getRuntime();
            System.out.println("处理器数量:"
                    + rt.availableProcessors());
            System.out.println("空闲内存数:"
                    + rt.freeMemory());
            System.out.println("总内存数:"
                    + rt.totalMemory());
            System.out.println("可用最大内存数:"
                    + rt.maxMemory());
        }
    }

    Runtime类可以直接单独启动一个进程来运行操作系统的命令:

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

    通过 ProcessHandle (Java 9) 获取进程的相关信息:

    import java.util.concurrent.*;
    
    public class ProcessHandleTest
    {
        public static void main(String[] args)
            throws Exception
        {
            Runtime rt = Runtime.getRuntime();
            // 运行记事本程序
            Process p = rt.exec("notepad.exe");
            ProcessHandle ph = p.toHandle();
            System.out.println("进程是否运行: " + ph.isAlive());
            System.out.println("进程ID: " + ph.pid());
            System.out.println("父进程: " + ph.parent());
            // 获取ProcessHandle.Info信息
            ProcessHandle.Info info = ph.info();
            // 通过ProcessHandle.Info信息获取进程相关信息
            System.out.println("进程命令: " + info.command());
            System.out.println("进程参数: " + info.arguments());
            System.out.println("进程启动时间: " + info.startInstant());
            System.out.println("进程累计运行时间: " + info.totalCpuDuration());
            // 通过CompletableFuture在进程结束时运行某个任务
            CompletableFuture<ProcessHandle> cf = ph.onExit();
            cf.thenRunAsync(()->{
                System.out.println("程序退出");
            });
            Thread.sleep(5000);
        }
    }

    常用类:

    Object类:

    调用Object实现的clone()方法来得到给对象的副本,并返回该副本。如下实现“自我克隆”:

    /**
     * Description:
     * 网站: <a href="http://www.crazyit.org">疯狂Java联盟</a><br>
     * Copyright (C), 2001-2018, Yeeku.H.Lee<br>
     * This program is protected by copyright laws.<br>
     * Program Name:<br>
     * Date:<br>
     * @author Yeeku.H.Lee kongyeeku@163.com
     * @version 1.0
     */
    
    class Address
    {
        String detail;
        public Address(String detail)
        {
            this.detail = detail;
        }
    }
    // 实现Cloneable接口
    class User implements Cloneable
    {
        int age;
        Address address;
        public User(int age)
        {
            this.age = age;
            address = new Address("广州天河");
        }
        // 通过调用super.clone()来实现clone()方法
        public User clone()
            throws CloneNotSupportedException
        {
            return (User)super.clone();
        }
    }
    public class CloneTest
    {
        public static void main(String[] args)
            throws CloneNotSupportedException
        {
            User u1 = new User(29);
            // clone得到u1对象的副本。
            User u2 = u1.clone();
            // 判断u1、u2是否相同
            System.out.println(u1 == u2);      //// 判断u1、u2的address是否相同
            System.out.println(u1.address == u2.address);     //
        }
    }

     

    Java7新增的Objects类:

    public class ObjectsTest
    {
        // 定义一个obj变量,它的默认值是null
        static ObjectsTest obj;
        public static void main(String[] args)
        {
            // 输出一个null对象的hashCode值,输出0
            System.out.println(Objects.hashCode(obj));
            // 输出一个null对象的toString,输出null
            System.out.println(Objects.toString(obj));
            // 要求obj不能为null,如果obj为null则引发异常
            System.out.println(Objects.requireNonNull(obj
                    , "obj参数不能是null!"));
        }
    }

    Math类:

    public class MathTest
    {
        public static void main(String[] args)
        {
            /*---------下面是三角运算---------*/
            // 将弧度转换角度
            System.out.println("Math.toDegrees(1.57):"
                    + Math.toDegrees(1.57));
            // 将角度转换为弧度
            System.out.println("Math.toRadians(90):"
                    + Math.toRadians(90));
            // 计算反余弦,返回的角度范围在 0.0 到 pi 之间。
            System.out.println("Math.acos(1.2):" + Math.acos(1.2));
            // 计算反正弦;返回的角度范围在 -pi/2 到 pi/2 之间。
            System.out.println("Math.asin(0.8):" + Math.asin(0.8));
            // 计算反正切;返回的角度范围在 -pi/2 到 pi/2 之间。
            System.out.println("Math.atan(2.3):" + Math.atan(2.3));
            // 计算三角余弦。
            System.out.println("Math.cos(1.57):" + Math.cos(1.57));
            // 计算值的双曲余弦。
            System.out.println("Math.cosh(1.2 ):" + Math.cosh(1.2 ));
            // 计算正弦
            System.out.println("Math.sin(1.57 ):" + Math.sin(1.57 ));
            // 计算双曲正弦
            System.out.println("Math.sinh(1.2 ):" + Math.sinh(1.2 ));
            // 计算三角正切
            System.out.println("Math.tan(0.8 ):" + Math.tan(0.8 ));
            // 计算双曲正切
            System.out.println("Math.tanh(2.1 ):" + Math.tanh(2.1 ));
            // 将矩形坐标 (x, y) 转换成极坐标 (r, thet));
            System.out.println("Math.atan2(0.1, 0.2):" + Math.atan2(0.1, 0.2));
            /*---------下面是取整运算---------*/
            // 取整,返回小于目标数的最大整数。
            System.out.println("Math.floor(-1.2 ):" + Math.floor(-1.2 ));
            // 取整,返回大于目标数的最小整数。
            System.out.println("Math.ceil(1.2):" + Math.ceil(1.2));
            // 四舍五入取整
            System.out.println("Math.round(2.3 ):" + Math.round(2.3 ));
            /*---------下面是乘方、开方、指数运算---------*/
            // 计算平方根。
            System.out.println("Math.sqrt(2.3 ):" + Math.sqrt(2.3 ));
            // 计算立方根。
            System.out.println("Math.cbrt(9):" + Math.cbrt(9));
            // 返回欧拉数 e 的n次幂。
            System.out.println("Math.exp(2):" + Math.exp(2));
            // 返回 sqrt(x2 +y2)
            System.out.println("Math.hypot(4 , 4):" + Math.hypot(4 , 4));
            // 按照 IEEE 754 标准的规定,对两个参数进行余数运算。
            System.out.println("Math.IEEEremainder(5 , 2):"
                    + Math.IEEEremainder(5 , 2));
            // 计算乘方
            System.out.println("Math.pow(3, 2):" + Math.pow(3, 2));
            // 计算自然对数
            System.out.println("Math.log(12):" + Math.log(12));
            // 计算底数为 10 的对数。
            System.out.println("Math.log10(9):" + Math.log10(9));
            // 返回参数与 1 之和的自然对数。
            System.out.println("Math.log1p(9):" + Math.log1p(9));
            /*---------下面是符号相关的运算---------*/
            // 计算绝对值。
            System.out.println("Math.abs(-4.5):" + Math.abs(-4.5));
            // 符号赋值,返回带有第二个浮点数符号的第一个浮点参数。
            System.out.println("Math.copySign(1.2, -1.0):"
                    + Math.copySign(1.2, -1.0));
            // 符号函数;如果参数为 0,则返回 0;如果参数大于 0,
            // 则返回 1.0;如果参数小于 0,则返回 -1.0。
            System.out.println("Math.signum(2.3):" + Math.signum(2.3));
            /*---------下面是大小相关的运算---------*/
            // 找出最大值
            System.out.println("Math.max(2.3 , 4.5):" + Math.max(2.3 , 4.5));
            // 计算最小值
            System.out.println("Math.min(1.2 , 3.4):" + Math.min(1.2 , 3.4));
            // 返回第一个参数和第二个参数之间与第一个参数相邻的浮点数。
            System.out.println("Math.nextAfter(1.2, 1.0):"
                    + Math.nextAfter(1.2, 1.0));
            // 返回比目标数略大的浮点数
            System.out.println("Math.nextUp(1.2 ):" + Math.nextUp(1.2 ));
            // 返回一个伪随机数,该值大于等于 0.0 且小于 1.0。
            System.out.println("Math.random():" + Math.random());
        }
    }

    Java7的ThreadLoaclRandom和Random

    ThreadLoaclRandom是Java7新增,是Random的增强版,在并发访问情况下,使用ThreadLoaclRandom代替Random可以减少多线程资源竞争,保证系统具有更好的线程安全性。

    Random类用法:

    public class RandomTest
    {
        public static void main(String[] args)
        {
            Random rand = new Random();
            System.out.println("rand.nextBoolean():"
                    + rand.nextBoolean());
            byte[] buffer = new byte[16];
            rand.nextBytes(buffer);
            System.out.println(Arrays.toString(buffer));
            // 生成0.0~1.0之间的伪随机double数
            System.out.println("rand.nextDouble():"
                    + rand.nextDouble());
            // 生成0.0~1.0之间的伪随机float数
            System.out.println("rand.nextFloat():"
                    + rand.nextFloat());
            // 生成平均值是 0.0,标准差是 1.0的伪高斯数
            System.out.println("rand.nextGaussian():"
                    + rand.nextGaussian());
            // 生成一个处于int整数取值范围的伪随机整数
            System.out.println("rand.nextInt():" + rand.nextInt());
            // 生成0~26之间的伪随机整数
            System.out.println("rand.nextInt(26):" + rand.nextInt(26));
            // 生成一个处于long整数取值范围的伪随机整数
            System.out.println("rand.nextLong():" +  rand.nextLong());
        }
    }

    Random使用一个48位的种子,如果这个类的两个实例使用同一个种子创建的,对他们以同样的顺序调用方法,则他们会产生相同的数字序列。

    public class SeedTest
    {
        public static void main(String[] args)
        {
            Random r1 = new Random(50);
            System.out.println("第一个种子为50的Random对象");
            System.out.println("r1.nextBoolean():	" + r1.nextBoolean());
            System.out.println("r1.nextInt():		" + r1.nextInt());
            System.out.println("r1.nextDouble():	" + r1.nextDouble());
            System.out.println("r1.nextGaussian():	" + r1.nextGaussian());
            System.out.println("---------------------------");
            Random r2 = new Random(50);
            System.out.println("第二个种子为50的Random对象");
            System.out.println("r2.nextBoolean():	" + r2.nextBoolean());
            System.out.println("r2.nextInt():		" + r2.nextInt());
            System.out.println("r2.nextDouble():	" + r2.nextDouble());
            System.out.println("r2.nextGaussian():	" + r2.nextGaussian());
            System.out.println("---------------------------");
            Random r3 = new Random(100);
            System.out.println("种子为100的Random对象");
            System.out.println("r3.nextBoolean():	" + r3.nextBoolean());
            System.out.println("r3.nextInt():		" + r3.nextInt());
            System.out.println("r3.nextDouble():	" + r3.nextDouble());
            System.out.println("r3.nextGaussian():	" + r3.nextGaussian());
        }
    }

    为了避免两个Random序列产生相同的数字序列,通常推荐使用当前时间作为Random对象的种子。

    BigDecimal类:

    使用基本类型的浮点数float、double容易引起数据丢失:

    public class DoubleTest
    {
        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));
        }
    }

    为此,Java提供了BigDecimal类,该类提供了大量构造器用于创建BigDecimal对象,包括把所有的基本数值类型变量转换成一个BigDecimal对象,也包括利用数字字符串、数字字符数组来创建BigDecimal对象,查看BigDecimal(double val)不推荐使用该构造器,因为使用该构造器有一定的不可预知性。

    BigDecimal的基本运算:

    public class BigDecimalTest
    {
        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));
        }
    }

    为了避免程序中对于double运算的繁琐,可以以BigDecimal基础定义一个Arith工具类:

    public class Arith
    {
        // 默认除法运算精度
        private static final int DEF_DIV_SCALE = 10;
        // 构造器私有,让这个类不能实例化
        private Arith()    {}
        // 提供精确的加法运算。
        public static double add(double v1,double v2)
        {
            BigDecimal b1 = BigDecimal.valueOf(v1);
            BigDecimal b2 = BigDecimal.valueOf(v2);
            return b1.add(b2).doubleValue();
        }
        // 提供精确的减法运算。
        public static double sub(double v1,double v2)
        {
            BigDecimal b1 = BigDecimal.valueOf(v1);
            BigDecimal b2 = BigDecimal.valueOf(v2);
            return b1.subtract(b2).doubleValue();
        }
        // 提供精确的乘法运算。
        public static double mul(double v1,double v2)
        {
            BigDecimal b1 = BigDecimal.valueOf(v1);
            BigDecimal b2 = BigDecimal.valueOf(v2);
            return b1.multiply(b2).doubleValue();
        }
        // 提供(相对)精确的除法运算,当发生除不尽的情况时.
        // 精确到小数点以后10位的数字四舍五入。
        public static double div(double v1,double v2)
        {
            BigDecimal b1 = BigDecimal.valueOf(v1);
            BigDecimal b2 = BigDecimal.valueOf(v2);
            return b1.divide(b2 , DEF_DIV_SCALE
                , RoundingMode.HALF_UP).doubleValue();
        }
        public static void main(String[] args)
        {
            System.out.println("0.05 + 0.01 = "
                + Arith.add(0.05 , 0.01));
            System.out.println("1.0 - 0.42 = "
                + Arith.sub(1.0 , 0.42));
            System.out.println("4.015 * 100 = "
                + Arith.mul(4.015 , 100));
            System.out.println("123.3 / 100 = "
                + Arith.div(123.3 , 100));
        }
    }

    日期时间

     Date类

    已经过时的Date

    public class DateTest
    {
        public static void main(String[] args)
        {
            Date d1 = new Date();
            // 获取当前时间之后100ms的时间
            Date d2 = new Date(System.currentTimeMillis() + 100);
            System.out.println(d2);
            System.out.println(d1.compareTo(d2));
            System.out.println(d1.before(d2));
        }
    }

    Calendar类是一个抽象类,他代表日历:

    public class CalendarTest
    {
        public static void main(String[] args)
        {
            Calendar c = Calendar.getInstance();
            // 取出年
            System.out.println(c.get(YEAR));
            // 取出月份
            System.out.println(c.get(MONTH));
            // 取出日
            System.out.println(c.get(DATE));
            // 分别设置年、月、日、小时、分钟、秒
            c.set(2003 , 10 , 23 , 12, 32, 23); //2003-11-23 12:32:23
            System.out.println(c.getTime());
            // 将Calendar的年前推1年
            c.add(YEAR , -1); //2002-11-23 12:32:23
            System.out.println(c.getTime());
            // 将Calendar的月前推8个月
            c.roll(MONTH , -8); //2002-03-23 12:32:23
            System.out.println(c.getTime());
    
    
            Calendar cal1 = Calendar.getInstance();
            cal1.set(2003, 7, 23, 0, 0 , 0); // 2003-8-23
            cal1.add(MONTH, 6); //2003-8-23 => 2004-2-23
            System.out.println(cal1.getTime());
    
    
            Calendar cal2 = Calendar.getInstance();
            cal2.set(2003, 7, 31, 0, 0 , 0); // 2003-8-31
            // 因为进位到后月份改为2月,2月没有31日,自动变成29日
            cal2.add(MONTH, 6); // 2003-8-31 => 2004-2-29
            System.out.println(cal2.getTime());
    
    
            Calendar cal3 = Calendar.getInstance();
            cal3.set(2003, 7, 23, 0, 0 , 0); //2003-8-23
            // MONTH字段“进位”,但YEAR字段并不增加
            cal3.roll(MONTH, 6); //2003-8-23 => 2003-2-23
            System.out.println(cal3.getTime());
    
    
            Calendar cal4 = Calendar.getInstance();
            cal4.set(2003, 7, 31, 0, 0 , 0); //2003-8-31
            // MONTH字段“进位”后变成2,2月没有31日,
            // YEAR字段不会改变,2003年2月只有28天
            cal4.roll(MONTH, 6); //2003-8-31 => 2003-2-28
            System.out.println(cal4.getTime());
        }
    }

    Java 8专门新增了一个java.time包,该包下包含了如下常用类: 
    Clock、Duration、LocalDate、LocalTime、LocalDateTime、MonthDay、Year、YearMonth、DayOfWeek、Month。

    public class NewDatePackageTest
    {
        public static void main(String[] args)
        {
            // -----下面是关于Clock的用法-----
            // 获取当前Clock
            Clock clock = Clock.systemUTC();
            // 通过Clock获取当前时刻
            System.out.println("当前时刻为:" + clock.instant());
            // 获取clock对应的毫秒数,与System.currentTimeMillis()输出相同
            System.out.println(clock.millis());
            System.out.println(System.currentTimeMillis());
            // -----下面是关于Duration的用法-----
            Duration d = Duration.ofSeconds(6000);
            System.out.println("6000秒相当于" + d.toMinutes() + "分");
            System.out.println("6000秒相当于" + d.toHours() + "小时");
            System.out.println("6000秒相当于" + d.toDays() + "天");
            // 在clock基础上增加6000秒,返回新的Clock
            Clock clock2 = Clock.offset(clock, d);
            // 可看到clock2与clock1相差1小时40分
            System.out.println("当前时刻加6000秒为:" +clock2.instant());
            // -----下面是关于Instant的用法-----
            // 获取当前时间
            Instant instant = Instant.now();
            System.out.println(instant);
            // instant添加6000秒(即100分钟),返回新的Instant
            Instant instant2 = instant.plusSeconds(6000);
            System.out.println(instant2);
            // 根据字符串中解析Instant对象
            Instant instant3 = Instant.parse("2014-02-23T10:12:35.342Z");
            System.out.println(instant3);
            // 在instant3的基础上添加5小时4分钟
            Instant instant4 = instant3.plus(Duration
                .ofHours(5).plusMinutes(4));
            System.out.println(instant4);
            // 获取instant4的5天以前的时刻
            Instant instant5 = instant4.minus(Duration.ofDays(5));
            System.out.println(instant5);
            // -----下面是关于LocalDate的用法-----
            LocalDate localDate = LocalDate.now();
            System.out.println(localDate);
            // 获得2014年的第146天
            localDate = LocalDate.ofYearDay(2014, 146);
            System.out.println(localDate); // 2014-05-26
            // 设置为2014年5月21日
            localDate = LocalDate.of(2014, Month.MAY, 21);
            System.out.println(localDate); // 2014-05-21
            // -----下面是关于LocalTime的用法-----
            // 获取当前时间
            LocalTime localTime = LocalTime.now();
            // 设置为22点33分
            localTime = LocalTime.of(22, 33);
            System.out.println(localTime); // 22:33
            // 返回一天中的第5503秒
            localTime = LocalTime.ofSecondOfDay(5503);
            System.out.println(localTime); // 01:31:43
            // -----下面是关于localDateTime的用法-----
            // 获取当前日期、时间
            LocalDateTime localDateTime = LocalDateTime.now();
            // 当前日期、时间加上25小时3分钟
            LocalDateTime future = localDateTime.plusHours(25).plusMinutes(3);
            System.out.println("当前日期、时间的25小时3分之后:" + future);
            // 下面是关于Year、YearMonth、MonthDay的用法示例-----
            Year year = Year.now(); // 获取当前的年份
            System.out.println("当前年份:" + year); // 输出当前年份
            year = year.plusYears(5); // 当前年份再加5年
            System.out.println("当前年份再过5年:" + year);
            // 根据指定月份获取YearMonth
            YearMonth ym = year.atMonth(10);
            System.out.println("year年10月:" + ym); // 输出XXXX-10,XXXX代表当前年份
            // 当前年月再加5年,减3个月
            ym = ym.plusYears(5).minusMonths(3);
            System.out.println("year年10月再加5年、减3个月:" + ym);
            MonthDay md = MonthDay.now();
            System.out.println("当前月日:" + md); // 输出--XX-XX,代表几月几日
            // 设置为5月23日
            MonthDay md2 = md.with(Month.MAY).withDayOfMonth(23);
            System.out.println("5月23日为:" + md2); // 输出--05-23
        }
    }

     

    变量处理和方法处理

    Java9增强的MethidHandle

    public class MethodHandleTest
    {
        // 定义一个private的类方法
        private static void hello()
        {
            System.out.println("Hello world!");
        }
        // 定义一个private的实例方法
        private String hello(String name)
        {
            System.out.println("执行带参数的hello" + name);
            return name + ",您好";
        }
        public static void main(String[] args) throws Throwable
        {
            // 定义一个返回值为void、不带形参的方法类型
            MethodType type = MethodType.methodType(void.class);
            // 使用MethodHandles.Lookup的findStatic获取类方法
            MethodHandle mtd = MethodHandles.lookup()
                    .findStatic(MethodHandleTest.class, "hello", type);
            // 通过MethodHandle执行方法
            mtd.invoke();
            // 使用MethodHandles.Lookup的findVirtual获取实例方法
            MethodHandle mtd2 = MethodHandles.lookup()
                    .findVirtual(MethodHandleTest.class, "hello",
                            // 指定获取返回值为String, 形参为String的方法类型
                            MethodType.methodType(String.class, String.class));
            // 通过MethodHandle执行方法,传入主调对象和参数
            System.out.println(mtd2.invoke(new MethodHandleTest(), "孙悟空"));
        }
    }

    Java9增强的VarHandle

    VarHandle主要用于动态操作数组的元素或对象的成员变量。

    class User
    {
        String name;
        static int MAX_AGE;
    }
    public class VarHandleTest
    {
        public static void main(String[] args)throws Throwable
        {
            String[] sa = new String[]{"Java", "Kotlin", "Go"};
            // 获取一个String[]数组的VarHandle对象
            VarHandle avh = MethodHandles.arrayElementVarHandle(String[].class);
            // 比较并设置:如果第三个元素是Go,则该元素被设为Lua
            boolean r = avh.compareAndSet(sa, 2, "Go", "Lua");
            // 输出比较结果
            System.out.println(r); // 输出true
            // 看到第三个元素被替换成Lua
            System.out.println(Arrays.toString(sa));
            // 获取sa数组的第二个元素
            System.out.println(avh.get(sa, 1)); // 输出Kotlin
            // 获取并设置:返回第三个元素,并将第三个元素设为Swift
            System.out.println(avh.getAndSet(sa, 2, "Swift"));
            // 看到第三个元素被替换成Swift
            System.out.println(Arrays.toString(sa));
    
            // 用findVarHandle方法获取User类中名为name,
            // 类型为String的实例变量
            VarHandle vh1 = MethodHandles.lookup().findVarHandle(User.class,
                "name", String.class);
            User user = new User();
            // 通过VarHandle获取实例变量的值,需要传入对象作为调用者
            System.out.println(vh1.get(user)); // 输出null
            // 通过VarHandle设置指定实例变量的值
            vh1.set(user, "孙悟空");
            // 输出user的name实例变量的值
            System.out.println(user.name); // 输出孙悟空
            // 用findVarHandle方法获取User类中名为MAX_AGE,
            // 类型为Integer的类变量
            VarHandle vh2 = MethodHandles.lookup().findStaticVarHandle(User.class,
                "MAX_AGE", int.class);
            // 通过VarHandle获取指定类变量的值
            System.out.println(vh2.get()); // 输出0
            // 通过VarHandle设置指定类变量的值
            vh2.set(100);
            // 输出User的MAX_AGE类变量
            System.out.println(User.MAX_AGE); // 输出100
        }
    }

    Java9改进的国际化和格式化

    获取Java所支持的国家和语言:

    public class LocaleList
    {
        public static void main(String[] args)
        {
            // 返回Java所支持的全部国家和语言的数组
            Locale[] localeList = Locale.getAvailableLocales();
            // 遍历数组的每个元素,依次获取所支持的国家和语言
            for (int i = 0; i < localeList.length ; i++ )
            {
                // 输出出所支持的国家和语言
                System.out.println(localeList[i].getDisplayCountry()
                        + "=" + localeList[i].getCountry()+ " "
                        + localeList[i].getDisplayLanguage()
                        + "=" + localeList[i].getLanguage());
            }
        }
    }

    Java8新增的日期、时间格式器

    使用DateTimeFormatter完成格式化:

    public class NewFormatterTest
    {
        public static void main(String[] args)
        {
            DateTimeFormatter[] formatters = new DateTimeFormatter[]{
                    // 直接使用常量创建DateTimeFormatter格式器
                    DateTimeFormatter.ISO_LOCAL_DATE,
                    DateTimeFormatter.ISO_LOCAL_TIME,
                    DateTimeFormatter.ISO_LOCAL_DATE_TIME,
                    // 使用本地化的不同风格来创建DateTimeFormatter格式器
                    DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL, FormatStyle.MEDIUM),
                    DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG),
                    // 根据模式字符串来创建DateTimeFormatter格式器
                    DateTimeFormatter.ofPattern("Gyyyy%%MMM%%dd HH:mm:ss")
            };
            LocalDateTime date = LocalDateTime.now();
            // 依次使用不同的格式器对LocalDateTime进行格式化
            for(int i = 0 ; i < formatters.length ; i++)
            {
                // 下面两行代码的作用相同
                System.out.println(date.format(formatters[i]));
                System.out.println(formatters[i].format(date));
            }
        }
    }

    使用DateTimeFormatter解析字符串

    public class NewFormatterParse
    {
        public static void main(String[] args)
        {
            // 定义一个任意格式的日期时间字符串
            String str1 = "2014==04==12 01时06分09秒";
            // 根据需要解析的日期、时间字符串定义解析所用的格式器
            DateTimeFormatter fomatter1 = DateTimeFormatter
                    .ofPattern("yyyy==MM==dd HH时mm分ss秒");
            // 执行解析
            LocalDateTime dt1 = LocalDateTime.parse(str1, fomatter1);
            System.out.println(dt1); // 输出 2014-04-12T01:06:09
            // ---下面代码再次解析另一个字符串---
            String str2 = "2014$$$4月$$$13 20小时";
            DateTimeFormatter fomatter2 = DateTimeFormatter
                    .ofPattern("yyy$$$MMM$$$dd HH小时");
            LocalDateTime dt2 = LocalDateTime.parse(str2, fomatter2);
            System.out.println(dt2); // 输出 2014-04-13T20:00
    
        }
    }
  • 相关阅读:
    bloom filter
    【转】单实例
    Log Structured Merge Trees(LSM) 原理
    【转】南网成立始末
    变电站综合自动化系统
    bsp tree
    Private Bytes,Working Set,Virtual Size的区别
    kdtree
    asp.net下载文件几种方式
    C# FTP操作
  • 原文地址:https://www.cnblogs.com/jiangwz/p/9243717.html
Copyright © 2011-2022 走看看