反射枚举和Lambda总结

反射是什么?

Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射(reflection)机制

Java程序中许多对象在运行时会出现两种类型:运行时类型(RTTI)和编译时类型,

例如:Person p = newStudent();这句代码中p在编译时类型为Person,运行时类型为Student。

程序需要在运行时发现对象和类的真实信息。而通过使用反射程序就能判断出该对象和类属于哪些类。

反射相关的类:

1:Class类->代表类的实体,在运行的Java应用程序中表示类和接口
2::Field类->代表类的成员变量/类的属性
3:Method类->代表类的方法
4:Constructor类->代表类的构造方法

一个.java文件编译成.class字节码文件在JVM的堆上,

例如:Class对象包含了类的信息,Class对象只有一个

public class TestDemo {
    public static void main(String[] args) {
        //验证class对象只有一个
        //获取class对象的三种方式:
        /**
         * 1.getclass
         */
        Student student = new Student();
        Class c1 = student.getClass();
        /**
         * 2.
         */
        Class c2 = Student.class;
        /**
         * 3.
         */
        try {
            Class c3 = Class.forName("com.fanshe.Student");//路径一定要写对
            System.out.println(c1 == c2); //true
            System.out.println(c2 == c3); //true
            System.out.println(c1 == c3);  //true
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
    }
}

双亲委派模型:(类似于递归)

反射枚举和Lambda总结_第1张图片

双亲委派模型的全面介绍以及优缺点:https://www.jianshu.com/p/9df9d318e838

反射优点和缺点
优点:
1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
3. 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺点:
1. 使用反射会有效率问题。会导致程序效率降低。具体参考这里:http://www.imooc.com/article/293679
2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 。

 

枚举:

主要用途是:将一组常量组织起来。

之前定义常量:

public static final int RED = 1;

使用枚举:优点:将常量组织起来统一进行管理

public enum TestEnum {
    RED("红色",1),BLACK("黑色",1),GREEN("绿色",3),WHITE("白色",4);  //都属于枚举对象
}

本质:是java.lang.Enum 的子类,也就是说,自己写的枚举类,就算没有显示的继承Enum ,但是其默认继承了这个类。

Enum的常用方法:

values() 以数组形式返回枚举类型的所有成员
ordinal() 获取枚举成员的索引位置
valueOf() 将普通字符串转换为枚举实例
compareTo() 比较两个枚举成员在定义时的顺序

public enum TestEnum {
    RED("红色",1),BLACK("黑色",1),GREEN("绿色",3),WHITE("白色",4);  //都属于枚举对象

    public String color;
    public int ordinal;
   
    TestEnum(String color,int ordinal) {
        this.color = color;
        this.ordinal = ordinal;
    }
    public static TestEnum getEnumKey (int key) {
        for (TestEnum t: TestEnum.values()) {
            if(t.ordinal == key) {
                return t;
            }
        }
        return null;
    }
public static void main2(String[] args) {
        TestEnum[] testEnums = TestEnum.values();
        for (int i = 0; i < testEnums.length; i++) {
            //打印内容
            //System.out.print(testEnums[i]+" ");
            //打印下标
            //System.out.print(testEnums[i].ordinal()+" ");
        }
        System.out.println(TestEnum.valueOf("BLACK"));

        TestEnum testEnum1 = BLACK;
        TestEnum testEnum2 = TestEnum.GREEN;
        System.out.println(testEnum1.compareTo(testEnum2));
        System.out.println(RED.compareTo(WHITE));

    }

    public static void main1(String[] args) {
        TestEnum testEnum2 = TestEnum.BLACK;
        switch (testEnum2) {
            case RED:
                System.out.println("red");
                break;
            case BLACK:
                System.out.println("black111");
                break;
            case WHITE:
                System.out.println("WHITE");
                break;
            case GREEN:
                System.out.println("black");
                break;
            default:
                break;
        }
    }
}

 枚举优点缺点
优点:
1. 枚举常量更简单安全 。
2. 枚举具有内置方法 ,代码更优雅
缺点:
1. 不可继承,无法扩展

枚举是否可以通过反射,拿到实例对象呢?

我们刚刚在反射里边看到了,任何一个类,哪怕其构造方法是私有的,我们也可以通过反射拿到他的实例对象,那
么枚举的构造方法也是私有的,我们是否可以拿到呢

答案:不能通过反射获取枚举类的实例

Lambda表达式:个人感觉就是为了简写代码用的

//函数式接口

//无返回值无参数
@FunctionalInterface
interface NoParameterNoReturn {
    //注意:只能有一个方法
    void test();
}
//无返回值一个参数
@FunctionalInterface
interface OneParameterNoReturn {
    void test(int a);
}
//无返回值多个参数
@FunctionalInterface
interface MoreParameterNoReturn {
    void test(int a,int b);
}
//有返回值无参数
@FunctionalInterface
interface NoParameterReturn {
    int test();
}
//有返回值一个参数
@FunctionalInterface
interface OneParameterReturn {
    int test(int a);
}
//有返回值多参数
@FunctionalInterface
interface MoreParameterReturn {
    int test(int a,int b);
}

public class TestDemo {
    public static void main(String[] args) {
        //有返回值无参数
        NoParameterReturn np = ()->{return 10;};
        NoParameterReturn np2 = ()->10;
        System.out.println(np.test());
        System.out.println(np2.test());
        //有返回值1个参数
        OneParameterReturn op = (int a)->{return a;};
        OneParameterReturn op2 = a -> a;
        System.out.println(op.test(20));
        System.out.println(op2.test(30));

        //有返回值多个参数
        MoreParameterReturn mr = (int a,int b)->{
            return a+b;
        };
        System.out.println(mr.test(1, 2));
        
        MoreParameterReturn mr2 = (a,b)-> a+b;
        System.out.println(mr2.test(3, 4));


    }

    //无返回值
    public static void main1(String[] args) {
        //无返回值无参数
        NoParameterNoReturn np = () ->{
            System.out.println("hello");
        };
        np.test();

        //无返回值一个参数
        /*OneParameterNoReturn op = (a)->{
            System.out.println(a);
        };*/
        OneParameterNoReturn op = a-> System.out.println(a);
        op.test(10);

        //无返回值多个参数
        MoreParameterNoReturn mp = (int a,int b)->{
            System.out.println(a+b);
        };
        mp.test(10,20);

    }

}

 

变量捕获:Lambda 表达式中存在变量捕获

1,匿名内部类

public static void main2(String[] args) {
        int a = 99;
        //a = 88;
        NoParameterNoReturn2 np = ()->{
            //a = 88;
            System.out.println(a);
        };
        np.test();
    }
    /**
     * 匿名内部类当中捕获的常量一定是常量或者是没有改变过的量
     * @param args
     */
    public static void main1(String[] args) {
        int a = 10;
        //匿名内部类
        new Test() {
          public void func() {
              System.out.println(a);
          }
        }.func();
    }

2.Lambda变量捕获

Collection接口: removeIf() spliterator() stream() parallelStream() forEach()
List接口: replaceAll() sort()
Map接口:getOrDefault() forEach() replaceAll() putIfAbsent() remove() replace()
computeIfAbsent() computeIfPresent() compute() merge()

//map中的forEach
    public static void main(String[] args) {
        HashMap map = new HashMap<>();
        map.put(1,"hello");
        map.put(2,"world");
        map.put(3,"hello");
        map.put(4,"lambda");
        map.forEach(new BiConsumer() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println("key: "+integer+" value: "+s);
            }
        });
        //Lambda表达式
        map.forEach((key,value)-> System.out.println("key: "+key+" value: "+value));
    }

    public static void main4(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("hello");
        list.add("abc");
        list.add("world");

        list.sort(new Comparator() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
        //Lambda表达式
        list.sort((o1,o2)->{return o1.compareTo(o2);});
        list.sort((o1, o2) -> o1.compareTo(o2));

        list.forEach((s)-> System.out.println(s));
    }
    //List接口forEach
    public static void main3(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("hello");
        list.add("world");

        list.forEach(new Consumer() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
        //Lambda表达式
        list.forEach((s)-> System.out.println(s));
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(java,反射,lambda)