zoukankan      html  css  js  c++  java
  • JavaSE学习总结第27天_反射 & 设计模式 & JDK5、7、8新特性

     

    27.01  反射_类的加载概述和加载时机

    类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。

    加载:就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。

    连接

      验证 是否有正确的内部结构,并和其他类协调一致

      准备 负责为类的静态成员分配内存,并设置默认初始化值

      解析 将类的二进制数据中的符号引用替换为直接引用

    初始化:

      创建类的实例

      访问类的静态变量,或者为静态变量赋值

      调用类的静态方法

      使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

      初始化某个类的子类

      直接使用java.exe命令来运行某个主类

    27.02  反射_类加载器的概述和分类

    类加载器:负责将.class文件加载到内在中,并为之生成对应的Class对象。

    类加载器的组成:

    Bootstrap ClassLoader 根类加载器

    也被称为引导类加载器,负责Java核心类的加载

    比如System,String等。在JDK中JRE的lib目录下rt.jar文件中

    Extension ClassLoader 扩展类加载器

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

    在JDK中JRE的lib目录下ext目录

    Sysetm ClassLoader 系统类加载器

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

    27.03  反射_反射概述

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

     

    要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

    27.04  反射_获取class文件对象的三种方式

    1:Object类的getClass()方法

    2:数据类型的静态属性class

    3:Class类中的静态方法:public static Class forName(String className)

    开发中使用第三种方式

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws ClassNotFoundException
     4     {
     5         // 方式1
     6         Student p = new Student();
     7         Class c1 = p.getClass();
     8 
     9         Student p2 = new Student();
    10         Class c2 = p2.getClass();
    11 
    12         System.out.println(p == p2);// false
    13         System.out.println(c1 == c2);// true
    14 
    15         // 方式2
    16         Class c3 = Student.class;
    17         System.out.println(c1 == c3);// true
    18 
    19         // 方式3
    20         //public static Class<?> forName(String className) throws ClassNotFoundException
    21         //返回与带有给定字符串名的类或接口相关联的 Class 对象
    22         Class c4 = Class.forName("com.test.Student");//类的全路径
    23         System.out.println(c1 == c4);// true
    24     }
    25 }

     

    27.05  反射_通过反射获取无参构造方法并使用

    获取无参构造方法

    public Constructor<?>[] getConstructors()throws SecurityException

    返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。

    public Constructor<?>[] getDeclaredConstructors()throws SecurityException

    返回 Constructor 对象的一个数组,这些对象反映此 Class 对象表示的类声明的所有构造方法。

    例1:

     1 Class c = Class.forName("com.test.Student");
     2 //获取所有公共构造方法
     3 Constructor[] cons = c.getConstructors();
     4 for(Constructor con : cons)
     5 {
     6     System.out.println(con);
     7 }
     8 System.out.println("--------------");
     9 //获取所有构造方法
    10 Constructor[] conss = c.getDeclaredConstructors();
    11 for(Constructor con : conss)
    12 {
    13     System.out.println(con);
    14 }

     

    例2:

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception
     4     {
     5         Class c = Class.forName("com.test.Student");
     6         // 获取单个构造方法
     7         // public Constructor<T> getConstructor(Class<?>... parameterTypes)
     8         // 参数表示的是:要获取的构造方法的构造参数个数及数据类型的class字节码文件对象
     9         Constructor con = c.getConstructor();// 返回的是构造方法对象
    10 
    11         // Person p = new Person();
    12         // System.out.println(p);
    13         // public T newInstance(Object... initargs)
    14         // 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
    15         Object obj = con.newInstance();
    16         System.out.println(obj);
    17         
    18          //Student p = (Student)obj;
    19          //p.show();
    20     }
    21 }

     

    27.06  反射_通过反射获取带参构造方法并使用

    获取带参构造方法

    例: 

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 获取字节码文件对象
     6         Class c = Class.forName("com.test.Student");
     7 
     8         // 获取带参构造方法对象
     9         // public Constructor<T> getConstructor(Class<?>... parameterTypes)
    10         Constructor con = c.getConstructor(String.class, int.class,String.class);
    11 
    12         // 通过带参构造方法对象创建对象
    13         // public T newInstance(Object... initargs)
    14         Object obj = con.newInstance("小明", 27, "上海");
    15         
    16         System.out.println(obj);
    17     }
    18 }

     

    27.07  反射_通过反射获取私有构造方法并使用

    获取私有构造方法

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 获取字节码文件对象
     6         Class c = Class.forName("com.test.Student");
     7 
     8         // 获取私有构造方法对象
     9         Constructor con = c.getDeclaredConstructor(String.class);
    10 
    11         // 用该私有构造方法创建对象
    12         // IllegalAccessException:非法的访问异常。
    13         // 暴力访问
    14         con.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查
    15         Object obj = con.newInstance("旺财");
    16 
    17         System.out.println(obj);
    18     }
    19 }

     

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

    获取成员变量

    public Field getField(String name)throws NoSuchFieldException,SecurityException

    返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

    public Field[] getDeclaredFields()throws SecurityException

    返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 获取字节码文件对象
     6         Class c = Class.forName("com.test.Student");
     7 
     8         // 通过无参构造方法创建对象
     9         Constructor con = c.getConstructor();
    10         Object obj = con.newInstance();
    11         System.out.println(obj);
    12 
    13         // 获取单个的成员变量
    14         // 获取address并对其赋值(公共的)
    15         Field addressField = c.getField("address");
    16         // public void set(Object obj,Object value)
    17         // 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。
    18         addressField.set(obj, "上海"); // 给obj对象的addressField字段设置值为"上海"
    19         System.out.println(obj);
    20 
    21         // 获取name并对其赋值(私有的)
    22         // NoSuchFieldException
    23         Field nameField = c.getDeclaredField("name");
    24         // IllegalAccessException
    25         nameField.setAccessible(true);
    26         nameField.set(obj, "小强");
    27         System.out.println(obj);
    28 
    29         // 获取age并对其赋值(默认的)
    30         Field ageField = c.getDeclaredField("age");
    31         ageField.setAccessible(true);
    32         ageField.set(obj, 27);
    33         System.out.println(obj);
    34     }
    35 }

     

    27.09  反射_通过反射获取无参无返回值成员方法并使用

    获取无参无返回值成员方法

    public Method[] getMethods()throws SecurityException

    返回本类的所有公共方法同时返回从 Object 类继承的所有公共方法。

    public Method[] getDeclaredMethods()throws SecurityException

    返回 自己的所有方法

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 获取字节码文件对象
     6         Class c = Class.forName("com.test.Student");
     7 
     8         Constructor con = c.getConstructor();
     9         Object obj = con.newInstance();
    10 
    11         // 获取单个方法并使用
    12         // public void show()
    13         // public Method getMethod(String name,Class<?>... parameterTypes)
    14         // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
    15         Method m1 = c.getMethod("show");
    16         // obj.m1(); // 错误
    17         // public Object invoke(Object obj,Object... args)
    18         // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
    19         m1.invoke(obj); // 调用obj对象的m1方法
    20     }
    21 }

     

    27.10  反射_通过反射获取带参带返回值成员方法并使用

    获取带参带返回值成员方法

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 获取字节码文件对象
     6         Class c = Class.forName("com.test.Student");
     7 
     8         Constructor con = c.getConstructor();
     9         Object obj = con.newInstance();
    10 
    11         // 获取单个方法并使用
    12         // public void show()
    13         // public Method getMethod(String name,Class<?>... parameterTypes)
    14         // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型
    15         Method m1 = c.getMethod("show");
    16         // obj.m1(); // 错误
    17         // public Object invoke(Object obj,Object... args)
    18         // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数
    19         m1.invoke(obj); // 调用obj对象的m1方法
    20 
    21         System.out.println("----------");
    22         // public void method(String s)
    23         Method m2 = c.getMethod("method", String.class);
    24         m2.invoke(obj, "hello");
    25         System.out.println("----------");
    26 
    27         // public String getString(String s, int i)
    28         Method m3 = c.getMethod("getString", String.class, int.class);
    29         Object objString = m3.invoke(obj, "hello", 100);
    30         System.out.println(objString);
    31         // String s = (String)m3.invoke(obj, "hello",100);
    32         // System.out.println(s);
    33         System.out.println("----------");
    34 
    35         // private void function()
    36         Method m4 = c.getDeclaredMethod("function");
    37         m4.setAccessible(true);
    38         m4.invoke(obj);
    39     }
    40 }

     

    27.11  反射_通过反射运行配置文件内容

    通过配置文件运行类中的方法

    反射:需要有配置文件配合使用。用class.txt代替。并且知道有两个键。className、methodName

    例:

     1 public class Test
     2 {
     3     public static void main(String[] args) throws Exception 
     4     {
     5         // 反射前的做法
     6         // Student s = new Student();
     7         // s.love();
     8         // Teacher t = new Teacher();
     9         // t.love();
    10         // Worker w = new Worker();
    11         // w.love();
    12         
    13         // 反射后的做法
    14         // 加载键值对数据
    15         Properties prop = new Properties();
    16         FileReader fr = new FileReader("class.txt");
    17         prop.load(fr);
    18         fr.close();
    19 
    20         // 获取数据
    21         String className = prop.getProperty("className");
    22         String methodName = prop.getProperty("methodName");
    23 
    24         // 反射
    25         Class c = Class.forName(className);
    26 
    27         Constructor con = c.getConstructor();
    28         Object obj = con.newInstance();
    29 
    30         // 调用方法
    31         Method m = c.getMethod(methodName);
    32         m.invoke(obj);
    33     }
    34 }

     

    上例中,如果需要运行其他的类只需要修改class.txt文件中的内容即可

    27.12  反射_通过反射越过泛型检查

    实现向ArrayList<Integer>中添加一个字符串数据

     1 public class ArrayListDemo 
     2 {
     3     public static void main(String[] args) throws Exception
     4     {
     5         // 创建集合对象
     6         ArrayList<Integer> array = new ArrayList<Integer>();
     7 
     8         // array.add("hello");
     9         // array.add(10);
    10 
    11         Class c = array.getClass(); // 集合ArrayList的class文件对象
    12         Method m = c.getMethod("add", Object.class);
    13 
    14         m.invoke(array, "hello"); // 调用array的add方法,传入的值是hello
    15         m.invoke(array, "world");
    16         m.invoke(array, "java");
    17 
    18         System.out.println(array);
    19     }
    20 }

     

    27.13  反射_通过反射写一个通用的设置某个对象的某个属性为指定的值

     1 public class Tool 
     2 {
     3     public void setProperty(Object obj, String propertyName, Object value)throws Exception
     4     {
     5         // 根据对象获取字节码文件对象
     6         Class c = obj.getClass();
     7         // 获取该对象的propertyName成员变量
     8         Field field = c.getDeclaredField(propertyName);
     9         // 取消访问检查
    10         field.setAccessible(true);
    11         // 给对象的成员变量赋值为指定的值
    12         field.set(obj, value);
    13     }
    14 }
    15 
    16 //测试类
    17 public class ToolDemo 
    18 {
    19     public static void main(String[] args) throws Exception 
    20     {
    21         Person p = new Person();
    22         Tool t = new Tool();
    23         t.setProperty(p, "name", "小明");
    24         t.setProperty(p, "age", 27);
    25         System.out.println(p);
    26         System.out.println("-----------");
    27 
    28         Dog d = new Dog();
    29 
    30         t.setProperty(d, "sex", '男');
    31         t.setProperty(d, "price", 12.34f);
    32 
    33         System.out.println(d);
    34     }
    35 }
    36 
    37 class Dog
    38 {
    39     char sex;
    40     float price;
    41 
    42     @Override
    43     public String toString() 
    44     {
    45         return sex + "---" + price;
    46     }
    47 }
    48 
    49 class Person 
    50 {
    51     private String name;
    52     public int age;
    53 
    54     @Override
    55     public String toString()
    56     {
    57         return name + "---" + age;
    58     }
    59 }

     

    27.14  反射_动态代理的概述和实现

    动态代理:在程序运行过程中产生的这个对象,而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来生成一个代理

     

    在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib

     

    Proxy类中的方法创建动态代理类对象

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,

         InvocationHandler h)throws IllegalArgumentException

    返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。最终会调用InvocationHandler的方法

    接口 InvocationHandler中的方法

    Object invoke(Object proxy,Method method,Object[] args) throws Throwable

    在代理实例上处理方法调用并返回结果。

     

    Proxy.newProxyInstance

    创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,

    也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,

    以$开头,proxy为中,最后一个数字表示对象的标号。

    System.out.println(u.getClass().getName());

     

    每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的invoke 方法来进行调用。

     

    Proxy类中创建动态代理对象的方法的三个参数:

    ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载

    Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了

    InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

     

     

    InvocationHandler接口中invoke方法的三个参数:

    proxy:代表动态代理对象

    method:代表正在执行的方法

    args:代表调用目标方法时传入的实参

    27.15  设计模式_模版设计模式概述和使用

    模版设计模式概述:模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现

    优点:使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求

    缺点:如果算法骨架有修改的话,则需要修改抽象类

    例:

     1 //模板
     2 public abstract class GetTime 
     3 {
     4     // 计算出一段代码的运行时间
     5     public long getTime()
     6     {
     7         long start = System.currentTimeMillis();
     8         code();
     9 
    10         long end = System.currentTimeMillis();
    11 
    12         return end - start;
    13     }
    14     public abstract void code();
    15 }
    16 
    17 //实现类
    18 public class ForDemo extends GetTime
    19 {
    20     @Override
    21     public void code() 
    22     {
    23         for (int x = 0; x < 100000; x++) 
    24         {
    25             System.out.println(x);
    26         }
    27     }
    28 }
    29 //测试类
    30 public class Practice 
    31 {
    32     public static void main(String[] args)
    33     {
    34         GetTime gt = new ForDemo();
    35         System.out.println(gt.getTime() + "毫秒");
    36     }
    37 }

     

    27.16  设计模式_装饰模式概述和使用

    装饰设计模式概述:装饰模式就是使用被装饰类的一个子类的实例,在客户端将这个子类的实例交给装饰类。是继承的替代方案

    优点:使用装饰模式,可以提供比继承更灵活的扩展对象的功能,它可以动态的添加对象的功能,并且可以随意的组合这些功能

    缺点:正因为可以随意组合,所以就可能出现一些不合理的逻辑

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args)
     4     {
     5         Person p = new Person();
     6 //        p.chifan();
     7         
     8         NewPerson p1 = new NewPerson(p);
     9         p1.chifan();
    10         
    11         NewPerson2 p2 = new NewPerson2();
    12         p2.chifan();
    13     }
    14 }
    15 
    16 class Person
    17 {
    18     void chifan()
    19     {
    20         System.out.println("吃饭");
    21     }
    22 }
    23 
    24 //这个类的出现是为了增强Person而出现的。
    25 class NewPerson//装饰设计模式
    26 {
    27     private Person p ;
    28     NewPerson(Person p)
    29     {
    30         this.p = p;
    31     }
    32     
    33     public void chifan()
    34     {
    35         System.out.println("开胃酒");
    36         p.chifan();
    37         System.out.println("甜点");
    38     }
    39 
    40 }
    41 
    42 
    43 class NewPerson2 extends Person//继承
    44 {
    45     public void chifan()
    46     {
    47         System.out.println("开胃酒");
    48         super.chifan();
    49         System.out.println("甜点");
    50     }
    51 }

     

    27.17  JDK5新特性_JDK5新特性回顾

    自动装箱和拆箱、泛型、增强for循环、静态导入、可变参数

    27.18  JDK5新特性_自己实现枚举类

    枚举概述:是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。

    举例:一周只有7天,一年只有12个月等。

    单例设计模式:单例类是一个类只有一个实例

    那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例。这才能是枚举类。

     

    例:

      1 //版本1
      2 public class Direction 
      3 {
      4     // 创建几个实例
      5     public static final Direction FRONT = new Direction();
      6     public static final Direction BEHIND = new Direction();
      7     public static final Direction LEFT = new Direction();
      8     public static final Direction RIGHT = new Direction();
      9 
     10     // 构造私有,不能无限的创建
     11     private Direction() 
     12     {}
     13 }
     14 ----------------------------------------------------------------------
     15 //版本2
     16 public class Direction2 
     17 {
     18     // 创建几个实例
     19     public static final Direction2 FRONT = new Direction2("前");
     20     public static final Direction2 BEHIND = new Direction2("后");
     21     public static final Direction2 LEFT = new Direction2("左");
     22     public static final Direction2 RIGHT = new Direction2("右");
     23     
     24     // 构造私有,别人就不能无限的创建了
     25     // private Direction2() {
     26     // }
     27     
     28     // 加入成员变量,并去掉无参构造
     29     private String name;
     30     
     31     private Direction2(String name) 
     32     {
     33         this.name = name;
     34     }
     35     
     36     public String getName() 
     37     {
     38         return name;
     39     }
     40 }
     41 ----------------------------------------------------------------------
     42 //版本3
     43 public abstract class Direction3 
     44 {
     45     // 创建几个实例
     46     public static final Direction3 FRONT = new Direction3("前") 
     47     {
     48         @Override
     49         public void show() 
     50         {
     51             System.out.println("前");
     52         }
     53 
     54     };
     55     public static final Direction3 BEHIND = new Direction3("后") 
     56     {
     57         @Override
     58         public void show() 
     59         {
     60             System.out.println("后");
     61         }
     62 
     63     };
     64     public static final Direction3 LEFT = new Direction3("左") 
     65     {
     66         @Override
     67         public void show()
     68         {
     69             System.out.println("左");
     70         }
     71 
     72     };
     73     public static final Direction3 RIGHT = new Direction3("右") 
     74     {
     75         @Override
     76         public void show() 
     77         {
     78             System.out.println("右");
     79         }
     80 
     81     };
     82 
     83     // 构造私有,别人就不能无限的创建了
     84     // private Direction2() {
     85     // }
     86 
     87     // 加入成员变量,并去掉无参构造
     88     private String name;
     89 
     90     private Direction3(String name) 
     91     {
     92         this.name = name;
     93     }
     94 
     95     public String getName() 
     96     {
     97         return name;
     98     }
     99 
    100     // 加入抽象方法
    101     public abstract void show();
    102 }
    103 ----------------------------------------------------------------------
    104 //测试
    105 public class DirectionDemo 
    106 {
    107     public static void main(String[] args) 
    108     {
    109         Direction d = Direction.FRONT;
    110         System.out.println(d); // cn.itcast_01.Direction@175078b
    111         System.out.println("------------------------------------");
    112         Direction2 d2 = Direction2.FRONT;
    113         System.out.println(d2);// cn.itcast_01.Direction2@11563ff
    114         System.out.println(d2.getName());
    115         d2 = Direction2.RIGHT;
    116         System.out.println(d2);
    117         System.out.println(d2.getName());
    118         System.out.println("------------------------------------");
    119         Direction3 d3 = Direction3.FRONT;
    120         System.out.println(d3);
    121         System.out.println(d3.getName());
    122         d3.show();
    123 
    124         d3 = Direction3.LEFT;
    125         System.out.println(d3);
    126         System.out.println(d3.getName());
    127         d3.show();
    128     }
    129 }

     

    27.19  JDK5新特性_通过enum实现枚举类

    格式:

    只有枚举项的枚举类

    public enum 枚举类名 

    {

    枚举项1,枚举项2,枚举项3…;

    }

    例:

      1 //版本1
      2 public enum Direction 
      3 {
      4     FRONT, BEHIND, LEFT, RIGHT;
      5 }
      6 ----------------------------------------------------------------------
      7 //版本2
      8 public enum Direction2 
      9 {
     10     FRONT("前"), BEHIND("后"), LEFT("左"), RIGHT("右");
     11 
     12     private String name;
     13 
     14     private Direction2(String name) 
     15     {
     16         this.name = name;
     17     }
     18 
     19     public String getName() 
     20     {
     21         return name;
     22     }
     23 }
     24 
     25 ----------------------------------------------------------------------
     26 //版本3
     27 public enum Direction3 
     28 {
     29     FRONT("前") 
     30     {
     31         @Override
     32         public void show() 
     33         {
     34             System.out.println("前");
     35         }
     36     },
     37     BEHIND("后") 
     38     {
     39         @Override
     40         public void show() 
     41         {
     42             System.out.println("后");
     43         }
     44     },
     45     LEFT("左") 
     46     {
     47         @Override
     48         public void show() 
     49         {
     50             System.out.println("左");
     51         }
     52     },
     53     RIGHT("右") 
     54     {
     55         @Override
     56         public void show() 
     57         {
     58             System.out.println("右");
     59         }
     60     };
     61 
     62     private String name;
     63 
     64     private Direction3(String name) 
     65     {
     66         this.name = name;
     67     }
     68 
     69     public String getName()
     70     {
     71         return name;
     72     }
     73 
     74     public abstract void show();
     75 }
     76 
     77 ----------------------------------------------------------------------
     78 //测试
     79 public class DirectionDemo 
     80 {
     81     public static void main(String[] args) 
     82     {
     83         Direction d = Direction.FRONT;
     84         System.out.println(d); // FRONT
     85         // public String toString()返回枚举常量的名称,它包含在声明中。
     86         System.out.println("-------------");
     87         Direction2 d2 = Direction2.FRONT;
     88         System.out.println(d2);
     89         System.out.println(d2.getName());
     90         System.out.println("-------------");
     91         Direction3 d3 = Direction3.FRONT;
     92         System.out.println(d3);
     93         System.out.println(d3.getName());
     94         d3.show();
     95         System.out.println("--------------");
     96 
     97         Direction3 dd = Direction3.FRONT;
     98         dd = Direction3.LEFT;
     99 
    100         switch (dd) 
    101         {
    102             case FRONT:
    103                 System.out.println("你选择了前");
    104                 break;
    105             case BEHIND:
    106                 System.out.println("你选择了后");
    107                 break;
    108             case LEFT:
    109                 System.out.println("你选择了左");
    110                 break;
    111             case RIGHT:
    112                 System.out.println("你选择了右");
    113                 break;
    114         }
    115     }
    116 }

    运行结果:

    FRONT
    -------------
    FRONT
    前
    -------------
    FRONT
    前
    前
    --------------
    你选择了左

    27.20  JDK5新特性_枚举的注意事项

    注意事项:

    1.定义枚举类要用关键字enum

    2.所有枚举类都是Enum的子类

    3.枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省 略。建议不要省略

    4.枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);

    5.枚举类也可以有抽象方法,但是枚举项必须重写该方法

    6.枚举在switch语句中的使用

    27.21  JDK5新特性_枚举类的常见方法

    1.public final int compareTo(E o)比较此枚举与指定对象的顺序。

    2.public final String name()返回此枚举常量的名称,在其枚举声明中对其进行声明。

    3.public final int ordinal()返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。 

    4.public String toString()返回枚举常量的名称,它包含在声明中。

    5.public static <T extends Enum<T>> T valueOf(Class<T> enumType, String name)

    返回带指定名称的指定枚举类型的枚举常量。

     

    例:

     1 public class Practice 
     2 {
     3     public static void main(String[] args)
     4     {
     5         // int compareTo(E o)
     6         Direction2 d21 = Direction2.FRONT;//0
     7         Direction2 d22 = Direction2.BEHIND;//1
     8         Direction2 d23 = Direction2.LEFT;//2
     9         Direction2 d24 = Direction2.RIGHT;//3
    10         System.out.println(d21.compareTo(d21));//0
    11         System.out.println(d21.compareTo(d24));//-3
    12         System.out.println(d24.compareTo(d21));//3
    13         System.out.println("---------------");
    14         // String name()
    15         System.out.println(d21.name());//FRONT
    16         System.out.println("--------------");
    17         // int ordinal()
    18         System.out.println(d21.ordinal());//0
    19         System.out.println(d22.ordinal());//1
    20         System.out.println("--------------");
    21         // String toString()
    22         System.out.println(d21.toString());//FRONT
    23         System.out.println(d22.toString());//BEHIND
    24         System.out.println("--------------");
    25         // <T> T valueOf(Class<T> type,String name)
    26         Direction2 d = Enum.valueOf(Direction2.class, "FRONT");
    27         System.out.println(d.getName());//
    28         System.out.println("----------------");
    29         // values()
    30         // 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便
    31         Direction2[] dirs = Direction2.values();
    32         for (Direction2 d2 : dirs) 
    33         {
    34             System.out.println(d2);
    35             System.out.println(d2.getName());
    36         }
    37     }
    38 }

     

    27.22  JDK7新特性_JDK7的六个新特性回顾和讲解

    二进制字面量

    JDK7开始,可以用二进制来表示整数(byte,short,int和long)。

    使用二进制字面量的好处是,可以使代码更容易被理解。语法非常简单,只要在二进制数值前面加 0b或者0B

    例:int x = 0b110110

    数字字面量可以出现下划线

    为了增强对数值的阅读性,如我们经常把数据用逗号分隔一样。JDK7提供了_对数据分隔。

    例:int x = 100_1000;

    注意事项:

    不能出现在进制标识和数值之间

    不能出现在数值开头和结尾

    不能出现在小数点旁边

    switch 语句可以用字符串

    泛型简化

    异常的多个catch合并

    try-with-resources 语句

    try(必须是java.lang.AutoCloseable的子类对象){…}

    好处:

    资源自动释放,不需要close()了

    把需要关闭资源的部分都定义在这里就行了

    主要是流体系的对象是这个接口的子类(JDK7的API)

    27.23  JDK8新特性_接口中也可以有方法

    例:

     1 interface Inter
     2 {
     3         //抽象方法
     4         public abstract void show();
     5         
     6         //default方法
     7         public default void defaultPrint() 
     8         {
     9             System.out.println("defaultPrint run");
    10         }
    11 
    12         //static方法
    13         public static void staticPrint()
    14         {
    15             System.out.println("staticPrint run");
    16         }
    17 }
    18 
    19 //实现类
    20 class InterImpl implements Inter
    21 {
    22         public void show()
    23         {
    24             System.out.println("重写接口中的方法");
    25         }
    26 }
    27 
    28 //测试类
    29 public class Demo
    30 {
    31         public static void main(String[] args) 
    32         {
    33             //Inter.defaultPrint();     //非静态方法不能直接使用 
    34             Inter.staticPrint();
    35             
    36             Inter i = new InterImpl();
    37             i.defaultPrint();
    38             i.show();
    39         }
    40 }
  • 相关阅读:
    ubuntu: 环境搭建
    [转]unable to resolve superclass of 的奇怪问题和一种解决方法!
    [转]如何利用ndk-stack工具查看so库的调用堆栈【代码示例】?
    [转]TCP、UDP数据包大小的确定
    [转]教大家如何打造使用Tcpview(tcp查看器
    [转]帐号登录事件(事件编号与描述)
    [转]一个基于完成端口的TCP Server Framework,浅析IOCP
    [转]宏的高级使用--##,__VA_ARGS__, __FILE__, __FUNCTION__等
    mysql5.5 Replication 主从同步
    [转]adb pull Permission denied及no such file错误
  • 原文地址:https://www.cnblogs.com/zhy7201/p/4550234.html
Copyright © 2011-2022 走看看