zoukankan      html  css  js  c++  java
  • JDK1.5java新特性

    JDK1.5java增加的新特性:

       自动装箱/拆箱      增强for     泛型      枚举      静态导入      可变参数

    1 自动装箱/拆箱

    * JDK1.5允许开发人员把一个基本类型直接赋给对应的包装类变量或者赋给Object类型的变量,这个过程称为自动装箱。

    * 自动装箱和自动拆箱相反,即把包装类对象直接赋给一个对应的基本类型变量。

    也就是基本类型与其对应的引用类型之间的转换,但是不能乱用,一般我们要采用基本类型,如果在使用时不注意,可能会造成程序低效率运行。

    int ----- Integer
    float ----- Float
    double ---- Double
    char ------- Character
    boolean ---- Boolean
    short ---- Short
    long ---- Long
    byte ---- Byte

    比如:

    Long  sum = 0;

    for(long i =0;i<10000;i++){

      sum += i;

    }

    此处造成程序低效率就在于频繁的进行拆箱装箱操作。注意sum被定义成了Long而不是long。

    还有两个高精度的类

      BigInteger

      BigDecimal


    2 增强for

    优缺点:

      优点:遍历更简单,在集合遍历中增强for就是代替迭代器的

      弊端:增强for的目标不能为null(即数组或集合不能为null),所以在遍历之前需要进行判断

    格式:

      for(元素数据类型 变量:数组或集合){

          ....................................
          使用变量,该变量就是集合或者数组中的元素
      }

    举例:

    String[]  names = {"小明","小李","小王"};

    for(String  name : names){

       System.out.println("hello "+name);

    }


    3 泛型

    引入泛型的好处:

         1)去除了原先必须的冗长的强制类型转换

         2)能够在编译期检测出错误,不至于在运行时才发现,消除了潜在的错误,提高代码运行的可靠性。

         3)使用XJad.exe反编译工具可以看到,在编译期间泛型被擦除。

    泛型基本应用:

    1)泛型类

    *把泛型定义在类上

    *格式:public class 类名<泛型类型1.....>

    *注意:泛型类型必须是引用类型

    2)泛型方法

    * 把泛型定义在方法上:方法可以接收任意类型

    * 格式:public<泛型类型> 返回类型 方法名(泛型类型)

    3)泛型接口

    * 把泛型定义在接口上

    * 格式:public interface 接口名<泛型类型1.....>

    例1:一个简单的泛型类

    package basic.demo;

    public class FanTypeClass<T>{
      private T obj;

      public T getObj() {
        return obj;
      }

      public void setObj(T obj) {
        this.obj = obj;
      }
    }

    测试类:

    package basic.demo;

    public class FanTypeDemo {
      public static void main(String[] args) {

        FanTypeClass<String> obj1 = new FanTypeClass<String>();  //使用泛型
        obj1.setObj("hello");   //这时候set方法接收的参数必须是String,如果不传该类型,在编译期就会报错
        String s = obj1.getObj();  //这种方式下不需要强转
        System.out.println(s);

        FanTypeClass obj2 = new FanTypeClass();  //没使用泛型
        obj2.setObj(3);
        int num = (int) obj2.getObj();          //需要进行强转,如果不小心写错了就会产生ClassCastException,即类型转换异常

        String num = (String)obj2.getObj();    //这样写在编译期并不会报错,但是一旦执行就会产生类型转换异常
        System.out.println(num);
      }
    }

    例2:泛型方法的使用

    package basic.demo;

    public class FanTypeMethod {
      public <T> void show(T t){
        System.out.println(t);
      }
    }

    测试类:

    package basic.demo;

    public class FanTypeDemo {
      public static void main(String[] args) {

        FanTypeMethod ft = new FanTypeMethod();
        ft.show("hello");
        ft.show(100);
        ft.show(true);

      }

    }

    输出结果:

    hello

    100

    true

    例3 泛型接口

    分为两种用法:子类实现时已知将来使用类型和子类实现时未知使用类型(这一种常见)

    package basic.demo;

    public interface FanTypeInter<T>{
      public abstract void show(T t);
    }

    package basic.demo;   //子类未知要使用的类型,故还是用泛型T

    public class FanTypeInterImpl<T>  implements FanTypeInter<T> {
      @Override
      public void show(T t) {
        System.out.println(t);
      }
    }

    测试:

    package basic.demo;

    public class FanTypeDemo {
      public static void main(String[] args) {
        FanTypeInter<String> fti1 = new FanTypeInterImpl<String>();
        fti1.show("hello");

        FanTypeInter<Integer> fti2 = new FanTypeInterImpl<Integer>();
        fti2.show(100);

      }

    }

    泛型高级应用(通配符):

    1)泛型通配符 <?>

      *任意类型,如果没有明确,那么就是Object以及任意的java类

    2)? extends E

      * 向下限定,E及其子类

    3)? super E

      * 向上限定,E及其父类

    例:理解高级应用:红色标注皆为错误用法

    package basic.demo;

    import java.util.ArrayList;
    import java.util.List;

    public class FanTypeSeniorDemo {
      public static void main(String[] args) {
        //泛型如果明确写,必须前后一致
        // List<Object> list1 = new ArrayList<Object>();
        // List<Object> list2= new ArrayList<Person>(); //error
        // List<Object> list3 = new ArrayList<Student>(); //error
        // List<Object> list4 = new ArrayList<Teacher>(); //error


        //?表示任意类型都是可以的
        // List<?> list1 = new ArrayList<Object>();
           // List<?> list2= new ArrayList<Person>();
        // List<?> list3 = new ArrayList<Student>();
        // List<?> list4 = new ArrayList<Teacher>();


        //? extends E 向下限定:E及其子类
        // List<? extends Person> list1 = new ArrayList<Object>(); //error
        // List<? extends Person> list2= new ArrayList<Person>();
        // List<? extends Person> list3 = new ArrayList<Student>();
        // List<? extends Person> list4 = new ArrayList<Teacher>();


        //? super E 向上限定 E及其父类
        List<? super Person> list1 = new ArrayList<Object>();
        List<? super Person> list2= new ArrayList<Person>();
        List<? super Person> list3 = new ArrayList<Student>(); //error
        List<? super Person> list4 = new ArrayList<Teacher>(); //error

      }

    }
    class Person{

    }
    class Student extends Person{

    }
    class Teacher extends Person{

    }


    4 枚举

     关键字Enum,用于定义一个枚举类

     为什么需要枚举?
    一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。

    枚举类具有如下特性
      枚举类也是一种特殊形式的Java类。
      枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
      与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
      枚举类也可以实现接口、或继承抽象类。
      JDK5中扩展了switch语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型。
      若枚举类只有一个枚举值,则可以当作单例设计模式使用。

    Java中声明的枚举类,均是java.lang.Enum类的子类,它继承了Enum类的所有方法。

    常用方法:
      name():返回此枚举常量的名称,在其枚举声明中对其进行声明。
      ordinal():返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。也可以称为索引
      valueOf(Class enumClass, String name)
      values()     此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。


    5 静态导入

    可以直接导入到方法的级别。

    格式:import static 包名....类名.方法名;

    注意:

      *方法必须是静态的

      *如果有多个同名的静态方法,容易不知道使用谁??这个时候要使用该特性,需要加前缀。由此可见,意义不大。所以一般不用,仅需知道就行。

    例1:使用静态导入,使用静态方法时直接使用。

    package basic.demo;

    import static java.lang.Math.max;
    import static java.lang.Math.min;

    public class StaticImportDemo {
      public static void main(String[] args) {

        int num1 = 23;
        int num2 = 30;

        max(num1,num2);
        min(num1,num2);
      }
    }

    例2:编写重名的静态方法,然后一起在StaticImportDemo使用:

    package basic.demo;

    public class MyMath {
      public static int max(int num1,int num2){
        return num1>num2?num1:num2;
      }

      public static int min(int num1,int num2){
        return num1>num2?num2:num1;
      }
    }

    package basic.demo;

    import static java.lang.Math.max;
    import static java.lang.Math.min;

    import static basic.demo.MyMath.max;
    import static basic.demo.MyMath.min;  //使用都加前缀了,也就不需要静态导包了


    public class StaticImportDemo {
      public static void main(String[] args) {

        int num1 = 23;
        int num2 = 30;

        java.lang.Math.max(num1,num2);  //必须加包名前缀,否则报错
        basic.demo.MyMath.min(num1,num2);//必须加包名前缀,否则报错,但是这样一加前缀就没有导包的意义了。。。。。
      }
    }


    6 可变参数

    Effective Java不建议使用该特性,而且在java编程思想中也说了此特性的隐患。

     *定义方法的时候不知道定义多少个参数,故引入可变参数的概念。

    使用格式:

      * 修饰符  返回值类型  方法名(数据类型...变量名){}

    注意:

     * 这里的变量其实是一个数组

       *如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个,否则编译器报错。

    举例:

      *Arrays工具类中的一个方法:

      public static <T>List<T> asList(T...a)

    例1:简单使用:

    package basic.demo;
    public class ChangeParaDemo {
      public static void main(String[] args) {
        int[] data = {1,2,3,4};
        System.out.println(sum(data));

        int sum = sum(2,3,4,5);
        System.out.println(sum);

        sum = sum(2,5);
        System.out.println(sum);
      }

      private static int sum(int...num) {
        int result = 0;
        for(int i:num){
          result += i;
        }
        return result;
      }
    }

    例2 方法中有多个参数:java在编译器期间就强调可变参数必须在最后的位置。

    package basic.demo;
    public class ChangeParaDemo {
      public static void main(String[] args) {
        int sum = sum(100,1,2,3,4);
        System.out.println(sum);       //如果把可变参数放在方法参数的最后,结果是10

        int sum = sum(1,2,3,4,100);

        System.out.println(sum);   //如果可变参数放在前面,会报错
      }

      private static int sum(int special,int...num) {
        int result = 0;
        for(int i:num){
          result += i;
        }
        return result;
      }

      //error: 错误写法

      //出错原因,因为可变参数变量其实是一个数组,如果把可变参数放在前面,则special变量被视为数组的一部分,也就是说你只传了一个参数,和原方法参数个数不一致

      private static int sum(int...num,int special) {
        int result = 0;
        for(int i:num){
          result += i;
        }
        return result;
      }

    }


  • 相关阅读:
    Failed at the node-sass@4.13.1 postinstall script. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
    页面跳转
    多行文字溢出显示省略号
    iview-select选择器组件的使用&设置默认选中的值
    iview中表单验证(遇到的问题)
    iview DatePicker type 为dateTime 时无法做表单验证!
    报错:[Vue warn]: Error in callback for watcher "value": "Value should be trueValue or falseValue."
    Jquery 数字滚动兼容小数
    validate表单验证-单独验证
    2020软件工程作业03
  • 原文地址:https://www.cnblogs.com/zwbg/p/5904183.html
Copyright © 2011-2022 走看看