标签:
------- android培训、java培训、期待与您交流! ----------
27.01 反射_类的加载概述和加载时机
类的加载:当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化。
加载:就是指将class文件读入内存,并为之创建一个Class对象。任何类被使用时系统都会建立一个Class对象。
连接
验证 是否有正确的内部结构,并和其他类协调一致
准备 负责为类的静态成员分配内存,并设置默认初始化值
解析 将类的二进制数据中的符号引用替换为直接引用
初始化:
创建类的实例
访问类的静态变量,或者为静态变量赋值
调用类的静态方法
使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
初始化某个类的子类
直接使用java.exe命令来运行某个主类
类加载器:负责将.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包和类路径
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的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文件中的内容即可
实现向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:代表调用目标方法时传入的实参
模版设计模式概述:模版方法模式就是定义一个算法的骨架,而将具体的算法延迟到子类中来实现
优点:使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的算法,满足用户灵活多变的需求
缺点:如果算法骨架有修改的话,则需要修改抽象类
例:
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循环、静态导入、可变参数
枚举概述:是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。
举例:一周只有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 前 前 -------------- 你选择了左
注意事项:
1.定义枚举类要用关键字enum
2.所有枚举类都是Enum的子类
3.枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但是如果枚举类有其他的东西,这个分号就不能省 略。建议不要省略
4.枚举类可以有构造器,但必须是private的,它默认的也是private的。枚举项的用法比较特殊:枚举(“”);
5.枚举类也可以有抽象方法,但是枚举项必须重写该方法
6.枚举在switch语句中的使用
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)
例:
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 }
黑马程序员_JavaSE学习总结第27天_反射 & 设计模式 & JDK5、7、8新特性
标签:
原文地址:http://www.cnblogs.com/zhy7201/p/4550234.html