目录
前言:
反射
获取Class对象
代码实现
常用方法代码实现(有详细注释)
优缺点
枚举
枚举基本操作代码实现
优缺点
Lambda表达式
Lambda表达式基本使用代码
优缺点
小结:
前言:
?java提供的反射机制是一把双刃剑,它打破了我们对原有访问修饰限定符的认知。枚举是一个特殊的类,可以将一些可能出现的情况枚举出来,以便于我们使用。lambda表达式是对代码的一种简写,可以让代码足够简单。
反射
?javac编译产生的class文件,对于JVM来说是一个对象,然后JVM就可以解析这个对象。我们也可以通过代码的实现来获取这个Class对象。当我们拿到这个对象的时候,就可以通过反射机制应用到这个实例,甚至可以得到或者修改这个对象的成员方法和属性。使这个类成为一个动态类。
获取Class对象
注意:有三种可以获取Class对象的方法,最常用的是全路径法。
代码实现
package demo3;public class Test2 { public static void main(String[] args) { //通过对象获取Class对象 Student student = new Student(); Class<?> c1 = student.getClass(); //通过类名获取Class对象 Class<?> c2 = Student.class; //全路径法获取Class对象 try { Class<?> c3 = Class.forName("demo3.Student"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } }}
常用方法代码实现(有详细注释)
package demo3;import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Test { public static void main(String[] args) { try { //生成Class对象 Class<?> c = Class.forName("demo3.Student"); //通过反射创建一个对象 Student student2 = (Student) c.newInstance(); //调用构造方法 Constructor<?> constructor = c.getDeclaredConstructor(int.class, String.class); //修改权限 constructor.setAccessible(true); //实例化对象 Student student1 = (Student)constructor.newInstance(21, "wuhao"); System.out.println(student1); //反射成员属性 Field field = c.getDeclaredField("name"); //修改权限 field.setAccessible(true); //实例化对象 Student student3 = (Student) c.newInstance(); //修改属性 field.set(student3, "qq"); //获取属性 String name = (String) field.get(student3); System.out.println(name); //反射成员方法 Method method = c.getDeclaredMethod("function", String.class); //获取方法名 System.out.println(method.getName()); //修改权限 method.setAccessible(true); //实例化对象 Student student4 = (Student) c.newInstance(); //给方法传参 method.invoke(student4, "ttt"); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (NoSuchMethodException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } catch (NoSuchFieldException e) { throw new RuntimeException(e); } }}
优缺点
优点:
?对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法。
?增加程序的灵活性和扩展性,降低耦合性,提高自适应能力。
?反射已经运用在了很多流行框架。
缺点:
?使用反射会有效率问题。会导致程序效率降低。
?反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。
枚举
?枚举是一个特殊的类,它是将常量组织起来,默认继承Enum类。通过类名就可以直接获取枚举对象。枚举对象是不能被反射的。
注意:当枚举对象具有参数后,需要提供构造方法,并且这个构造方法必须是私有的。
枚举基本操作代码实现
package enumDemo;//默认继承Enum类//枚举不能被反射public enum Colour { RED("aa", 10),BLACK("w", 20),GREEN("yy",50),WHITE("kk", 6); private String name; private int age; public static void main(String[] args) { Colour[] colours = Colour.values(); for(int i = 0; i < colours.length; i++) { System.out.println(colours[i]); } } //枚举是一个类,通过类名就可以访问其中的枚举对象 //构造方法必须是私有的 //枚举对象在构造时,必须在后面调用构造方法。 private Colour(String name, int age) { this.name = name; this.age = age; }}enum Color2 { //0 1 2 3 RED,BLACK,GREEN,WHITE; public static void main(String[] args) { //将字符串转为枚举对象,需原来就包含此对象 System.out.println(Color2.valueOf("WHITE")); //得到枚举实例 Color2 color1 = Color2.RED; Color2 color2 = Color2.GREEN; System.out.println(color1.compareTo(color2)); System.out.println(RED.compareTo(WHITE)); System.out.println(WHITE.compareTo(BLACK)); //用于switch case语句 switch (RED) { case RED: System.out.println("aaaa"); break; case BLACK: break; case GREEN: break; case WHITE: break; } //将枚举对象转换为数组 Color2[] tmp = Color2.values(); //获取枚举成员的索引位置 System.out.println(tmp[2].ordinal()); }}
优缺点
优点:
?枚举常量更简单安全 。
?枚举具有内置方法 ,代码更优雅。
缺点:
?不可继承,无法扩展。
Lambda表达式
?Lambda表达式形式为:() -> {};。()内类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。{}内可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不返回。
?通常应用于函数式接口,和匿名内部类的简写。其实两者是一样的理解,应用于函数式接口其实就是匿名类实现了这个接口,然后简写了这个匿名类。
?一些集合类的方法参数就是函数式接口去接收的,我们就可以用Lambda表达式。
Lambda表达式基本使用代码
package lambdaDemo;import java.util.*;//函数式接口,只有一个函数@FunctionalInterfaceinterface MoreParameterReturn { int test(int a,int b);}public class LambdaDemo { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); //lambda表达式()内为形参,->后面为函数体 //用于函数式接口 list.sort((o1, o2) -> o2 - o1); list.forEach(s -> System.out.println(s)); HashMap<String, Integer> map = new HashMap<>(); map.put("wuhao", 8); map.put("www", 9); map.put("hhh",6); map.forEach((key, val) -> System.out.println(key +" " + val)); } public static void main1(String[] args) { //匿名内部类 PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; } }); //lambda表达式用于对匿名内部类的简化 PriorityQueue<Integer> priorityQueue1 = new PriorityQueue<>((o1, o2) -> o1 - o2); MoreParameterReturn moreParameterReturn1 = new MoreParameterReturn() { @Override public int test(int a, int b) { return a + b; } }; //lambda表达式()内为形参,->后面为函数体 MoreParameterReturn moreParameterReturn = (a, b) -> a + b; System.out.println(moreParameterReturn.test(10, 20)); }}
优缺点
优点:
?有利于代码的简写。
缺点:
?代码可读性差。
小结:
?我们在实际写代码时可以去尝试利用这样语法,相信会加深对其的理解性。