zoukankan      html  css  js  c++  java
  • java的几个奇怪语法

    =============================
    Java 双冒号 :: 语法的含义
    =============================
    下面的代码中有双冒号,初看上去很奇怪,
    list.forEach(System.out::println);

    这是Java8的"方法引用", 语法是 类名::静态方法名, 一般用作简化Lamda表达式.
    详见讨论: https://www.zhihu.com/question/28565691
    比如:
    list.forEach(System.out::println) 等价于 list.forEach(i->System.out.println(i))
    nameList.forEach(Person::new) 等价于 nameList.forEach(name->new Person(name))

    =============================
    Java 三个点 ... 参数的含义
    =============================
    Java 1.5引入了三个点...语法, 即可变参数语法. 既然是可变参数语法, 说明它仅仅能用于函数参数定义, 另外也只能用于最后一个参数. 在函数体中, 这个可变参数可以被看作是一个数组; 而在函数调用方面, 可以为该参数传入: 一个数组实参, 或者0个参数, 或者多个实参.

    可变参数的函数, 比普通的数组参数函数使用更灵活. 详见示例:

    public class App
    {
        static void test1(String...names)
        {
           for(String name:names){
              System.out.println(name);
           }
           System.out.println("end of test1");
        }
    
        static void test2(String[] names)
        {
           for(String name:names){
              System.out.println(name);
           }
           System.out.println("end of test2");
        }
    
        public static void main(String[] args) {
            test1(new String[] {"a","b"});
            test1("a","b");
            test1(); //甚至可以不传参数
    
            test2(new String[] {"a","b"});
            //test2();  //不传参数将报语法错误
            test2(new String[] {}); //传个空数组, 相当于不传参数
        }
    }

    =============================
    @interface vs interface
    =============================
    都知道 interface 关键词用来定义一个接口, 但发现 @interface 好像也是在定义一个接口, @interface是什么东西?
    原来@interface是用来定义annotation的, 定义annotation的写法和普通的interface很像, 下面是一个annotation定义的示例和使用.

    public @interface ClassPreamble {
       String author();
       String date();
       int currentRevision() default 1;
       String lastModified() default "N/A";
       String lastModifiedBy() default "N/A";
       // Note use of array
       String[] reviewers();
    }
    @ClassPreamble (
       author = "John Doe",
       date = "3/17/2002",
       currentRevision = 6,
       lastModified = "4/12/2004",
       lastModifiedBy = "Jane Doe",
       // Note array notation
       reviewers = {"Alice", "Bob", "Cindy"}
    )
    public class Generation3List extends Generation2List {
    
    // class code goes here
    
    }

    =======================
    SomeClass.class 和 SomeObject.getClass()
    =======================
    Print myPrint = new Print();
    System.out.println(Print.class.getName());
    System.out.println(myPrint.getClass().getName());

    经常能看到 SomeClass.class 这样的表达式, 该表达式和 SomeObject.getClass() 返回值是一样的, 都是返回一个 java.lang.Class 子类型对象, class是静态方法,注意它确实是方法, 但不需要加()号, getClass()是一个函数方法. 另外, .class还适用于原始类型, getClass()却不支持原始类型.

    摘自 https://stackoverflow.com/questions/15078935/what-does-class-mean-in-java

    =======================
    怎么理解函数返回类型是 <T> void
    =======================
    public <T> void foo(List<T> listOfT) {...}
    函数返回类型是 <T> void, 到底有没有返回值? 其实void 之前的<T>没有任何实际意义, 返回类型仍然是 void, void 之前的<T> 仅仅是一个提示, 告诉我们该函数参数是泛型.

    或者可以将这个提示加到类名后, 也是可以的.

    // 泛型类型提示加到函数上
    public class App{
        public <T> void foo(List<T> listOfT)    {
        }
    }
    
    // 泛型类型提示加到类名后
    public class App<T>{
        public void foo(List<T> listOfT)    {
        }
    }

    下面是一个多个泛型类型函数的提示:
    public <T,W> void bar(List<T> listOfT, List<W> listOfW) {...}
    摘自, https://stackoverflow.com/questions/11377248/return-type-of-java-generic-methods

    =======================
    <T> 和 <?> 的区别
    =======================
    public <T> void foo(List<T> listOfT) {...}
    public void bar(List<?> listOfSomething) {...}
    <?>意思是可以使用任何类型, 所以上面两个函数从功能上是一样的, 但仍有一些差别.
    最终的差异有: 第一个函数体中, 我们有一个类型变量T, 在函数体中可以用T定义另一个变量, 而第二个函数就做不到.
    还有一些其他差异详见 https://stackoverflow.com/questions/6008241/what-is-the-difference-between-e-and-t-for-java-generics

    =============================
    catch括号中包含多个Exception类名
    =============================

    try {
    execute(); //exception might be thrown
    } catch (IOException | SQLException ex) {
    LOGGER.error(ex);
    } catch (CustomException ex) {
    // do something else with this custom exception
    }

    代码中 catch (IOException | SQLException ex) 两个类名, 这是 Java7的语法, 如果针对两个类型的Exception有同样的处理机制, 可以在catch() 中用竖线符号将这些类型并列起来.

  • 相关阅读:
    mingw-gcc-10.0.1-experimental-i686-posix-sjlj-20200202-0303907
    可以修改 QtScrcpy 窗口大小的小工具
    autosub 添加代理服务器参数 -P --proxy
    Python网络数据采集系列-------概述
    【刷题笔记】I'm stuck! (迷宫)-----java方案
    【刷题笔记】火车购票-----java方案
    mvc自定义全局异常处理
    使用html2canvas实现浏览器截图
    再谈Newtonsoft.Json高级用法
    Spire.Doc组件读取与写入Word
  • 原文地址:https://www.cnblogs.com/harrychinese/p/java_syntax.html
Copyright © 2011-2022 走看看