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
    
        }
    }
  • 相关阅读:
    hdu 3666 差分约束系统
    hdu 1198农田灌溉
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    高等微積分(高木貞治) 1.4節 例2
    常微分方程(阿諾爾德) Page 45 相空間,相流,運動,相曲線 註記
    解析函數論 Page 29 命題(2) 函數模的有界性
    高等微積分(高木貞治) 1.4節 例2
    解析函數論 Page 29 命題(1) 有界閉集上的一致連續性
    解析函數論 Page 29 命題(3) 模的下界的可達性
    解析函數論 Page 29 命題(2) 函數模的有界性
  • 原文地址:https://www.cnblogs.com/jiangwz/p/9243717.html
Copyright © 2011-2022 走看看