• java自学之路二十二(jdk新特性二)


    补充

    Math补充

    e 自然对数的底数,pi 圆周率,pow幂函数

    BigDecimal

    进行浮点数计算

    public static void main(String[] args) {
        System.out.println(0.09+0.01);
        BigDecimal bd1 = new BigDecimal("0.09");
        BigDecimal bd2 = new BigDecimal("0.01");
        System.out.println(bd1.add(bd2));
    }
    

    Vector特有功能

    1. public void addElement(object,obj)
    2. public object elementAt(int index)

    特有功能被get add 取代

    TreeSet

    能够对元素按照某种规则进行排序

    1. 自然排序

      真正的比较依赖于元素的compareTo()方法,而这个方法是定义在comparable里面的,所以要重写该方法,就必须是先comparable接口,这个接口表示自然排序

      利用二叉树保证元素的大小和唯一性

      public class DemoTreeSet {
          public static void main(String[] args) {
              TreeSet<Integer> ts = new TreeSet<>();
              ts.add(20);
              ts.add(18);
              ts.add(23);
              ts.add(20);
              ts.add(17);
              System.out.println(ts);
          }
      }
      
    2. 比较器排序

    类加载器

    负责将.class文件加载到内存中,并为之生成对应的Class对象

    组成:

    • Bootstrap ClassLoader 根类加载器

      引导类加载器,负责java核心类的加载,比如system,string等在JDK中JRE的lib下rt.jar文件中

    • Extension ClassLoader 扩展类加载器

      负责jre扩展目录中jar包的加载

    • System ClassLoader 系统类加载器

      负责在jvm启动时加载来自java命令的class文件,以及classpath环境变量指定的jar包和类路径

    反射

    通过class文件对象,去使用该文件中的成员变量Field,构造方法Constructor,成员方法Method

    获取class文件对象的方式

    1. Object类的getClass()方法

      public static void main(String[] args) {
          Person p1 = new Person("janice",32);
          Person p2 = new Person("hawi",13);
      
          System.out.println(p1 == p2);
          System.out.println(p1.getClass() == p2.getClass());
      
      }
      
    2. 点class方法

      System.out.println(Person.class == p1.getClass());
      
    3. Class类中的静态方法

      Class c4 = Class.forName("practice2.demo.demo1012.Person");
      // 必须是包的全路径
      System.out.println(c4 == Person.class);
      

    获取公共构造方法

    Constructor[] constructors = c4.getConstructors();
    for(Constructor c:constructors){
        System.out.println(c);
    }
    public practice2.demo.demo1012.Person()
    public practice2.demo.demo1012.Person(java.lang.String,int)
    

    注意:getDeclaredConstructors获取所有构造方法,包括无public修饰和private私有

    Constructor[] constructors1 = c4.getDeclaredConstructors();
    for(Constructor c:constructors1){
        System.out.println(c);
    }
    

    获取单个构造方法

    参数表示的是:要获取的构造方法的构造参数个数己数据类型的class字节码文件对象

    获得构造方法对象后可以用来创建该构造方法的声明类实例,并用指定的参数初始化该实例。

    Constructor c4Constructor = c4.getConstructor(); // 获取无参数构造方法
    Object obj = c4Constructor.newInstance(); 
    System.out.println(obj);
    
    Constructor c4Constructor1 = c4.getConstructor(String.class, int.class); // 带参数构造方法
    Object obj2 = c4Constructor1.newInstance("23",34);
    System.out.println(obj2);
    

    获取私有构造方法

    getDeclaredConstructor() 获取所有构造方法

    IllegalAccessException 非法的访问异常(访问类的私有方法)

    解决:con.SetAccessible(true) // con是获取的构造方法

    通过反射获取成员变量并使用

    同上,具有获取私有成员变量和公共成员变量的功能以及单个成员变量

    Field[] fields = c4.getDeclaredFields();
    for(Field i:fields){
        System.out.println(i);
    }
    
    Field name = c4.getDeclaredField("name");
    Constructor constructor = c4.getConstructor();
    Object obj = constructor.newInstance();
    name.setAccessible(true);
    name.set(obj,"hhh");
    System.out.println(obj);
    

    c4是类对象,类对象可以获得成员变量,构造方法,成员方法

    con是构造器,可以构造对象

    获取的field 对象 setAccessible

    获取成员方法

    • 获取所有方法

      getMethods(包括父类的)

      1. 实例化对象
      2. 获取成员方法
      3. 用对象来调用成员方法
      Object obj = c.getConstructor().newInstance();  
      // getMethod(String name, Class<?>... parameterTypes)
      Method m1 = c.getMethod("show")
      // public Object invoke(Object obj, Object...args) 返回值是Object接收,第一个参数表示对象是谁,第二个参数表示调用该方法的实际参数
      m1.invoke(obj)  本质是调用obj对象的m1方法
      
      

      , getDeclaredMethods

    • 获取单个方法

    getMethod, getDeclaredMethod

    • 暴力访问

      method.setAccessible(true)

    往泛型是Integer的ArrayList中放String

    注意:泛型是给编译器看的,实际上jvm运行中按照obj来处理

    所以可以用反射来获取add方法,自定义添加数据类型

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<Integer> arr = new ArrayList<>();
    
        Class<? extends ArrayList> c = arr.getClass();
        Method m1 = c.getMethod("add",Object.class);
        m1.invoke(arr,"hello");
    
        arr.add(3);
    
        System.out.println(arr);
    }
    // [hello, 3]
    

    动态代理

    Java.lang.reflect.Proxy

    Proxy提供用于创建动态代理类和实例的静态方法,它是由这些方法创建的所有动态代理的超类。

    主程序:

    public static void main(String[] args){
    	User user = new UserImpl();
    	user.add();
    	user.del();
    	user.update();
    	user.list();
    	// 想对谁做代理传谁
    	MyInvocationHandler handler = new MyInvocationHandler(user);
    	User proxy = (User)Proxy.newProxyInstance(
    	user.getClass.getClassLoader,  // 类加载器
    	user.getClass.getInterface,   // 接口类
    	handler  
    	) // 可以用Object对象接受,实际上是User对象
    	proxy.add()
    	proxy.del()
    	proxy.update()
    	proxt.list()
    }
    
    public class MyInvocationHandler implements InvocationHandler {
        private Object target;  // 目标对象
    
        public MyInvocationHandler(Object target){
            this.target = target;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("前置处理");
            Object result = method.invoke(target, args);
            System.out.println("后置处理");
            return result;  // 返回的是代理对象
        }
    }
    

    枚举

    将变量的值一一列出来,变量的值只限于列举出来的值的范围内

    一、

    注意:抽象类不能实例化

    public enum Dirction {
        FRONT,BEHIND,LEFT,RIGHT
    }
    

    打印直接调用toString方法而不是地址值

    二、引用成员变量

    public enum Direction2 {
        FRONT("前"),
        BEHIND("后"),
        LEFT("左"),
        RIGHT("右");
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private String name;
    
        Direction2(String name) {
            this.name = name;
        }
    }
    
    Direction2 front = Direction2.FRONT;
    System.out.println(front.getName());
    

    三、抽象方法

    public enum Direction3 {
        FRONT("前"){
            @Override
            public void show() {
                System.out.println("1");
            }
        },
        BEHIND("后"){
            @Override
            public void show() {
                System.out.println("2");
            }
        },
        LEFT("左"){
            @Override
            public void show() {
                System.out.println("3");
            }
        },
        RIGHT("右"){
            @Override
            public void show() {
                System.out.println("4");
            }
        },;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        private String name;
    
        Direction3(String name) {
            this.name = name;
        }
    
        public abstract void show();
    }
    
    Direction3 behind1 = Direction3.BEHIND;
    behind1.show();
    

    注意:

    1. 定义枚举类要用关键字enum
    2. 所有枚举类都是Enum的子类
    3. 枚举类第一行必须是枚举项
    4. 枚举类可以有构造器,但必须是private,默认也是private的
    5. 枚举类也可以有抽象方法,但是必须重写该方法

    常用方法

    • compareTo,枚举的顺序
    Direction2 d21 = Direction2.FRONT;
    Direction2 d22 = Direction2.BEHIND;
    Direction2 d23 = Direction2.LEFT;
    Direction2 d24 = Direction2.RIGHT;
    
    System.out.println(d21.compareTo(d24));
    
    • Ordinal,返回枚举的序数

      System.out.println(d22.ordinal());
      
    • valuesOf

      Direction2 d = Enum.valueOf(Direction2.class,"FRONT");
      System.out.println(d.getName());
      
    • values() 遍历枚举项的枚举值

      Direction2[] dirs = Direction2.values();
      for(Direction2 dir:dirs){
          System.out.println(dir.getName());
      }
      

    JDK7新特性

    二进制,十六进制,八进制字面量

    public static void main(String[] args) {
        int x = 0b101010;
        System.out.println(x);
    
        int y = 0x1001;
        System.out.println(y);
    
        int z = 01101;
        System.out.println(z);
    }
    

    下划线当作数字分隔符

    int x = 100_1000;
    System.out.println(x);
    

    try改进

    将需要关闭的资源放在try后面的小括号里,必须是java.lang.AutoCloseable子类对象

    大部分流体系的对象是这个接口的子类

    try(FileReader fr = new FileReader(a.txt));
    		FileWriter = fw = new FilwWriter(b.txt);){
    			while((ch = fr.read()) != -1){
    				fw.writer(ch)
    			}cathc(IoException e){
    				e.printStackTrace();
    			})
    		}
    

    JDK8新特性

    在接口类中可以定义默认方法和静态方法

    Optional类

    是一个容器类,可以保存类型T的值,代表这个值存在,或者仅仅保存null,表示不存在。 避免空指针异常。

        public String getBoyName(Girl girl){
            Optional<Girl> girl1 = Optional.ofNullable(girl);
            Girl girl2 = girl1.orElse(new Girl(new Boy("kawii")));
    
            Boy boy = girl2.getBoy();
            Optional<Boy> boy1 = Optional.ofNullable(boy);
            Boy boy2 = boy1.orElse(new Boy("kawii2"));
            girl2.setBoy(boy2);
    
    
            System.out.println(girl1);
    //        Girl girl2 = girl1.orElse(new Girl(boy2));
    
            return girl2.getBoy().getName();
        }
    
        @Test
        public void test3(){
    //        Girl girl = new Girl();
            Girl girl = null;
            String boyName = getBoyName(girl);
            System.out.println(boyName);
        }
    
  • 相关阅读:
    学机器学习,不会数据分析怎么行——数据可视化分析(matplotlib)
    关于 tensorflow-gpu 中 CUDA 和 CuDNN 版本适配问题
    人工智能学习资料
    JAVA Socket通信 打造属于自己的网盘
    在 Windows 10 中使用 OpenAI Spinning Up
    【LeetCode】回文串专题
    【LeetCode】45.跳跃游戏2
    【LeetCode】23.最大子序和
    【LeetCode】3. 无重复字符的最长子串(典型滑动窗口)
    【LeetCode】202.快乐数
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/12367902.html
Copyright © 2020-2023  润新知