反射、枚举、lambda——小记
创始人
2024-02-16 04:02:44
0

文章目录

  • 反射
    • 反射定义
    • 反射相关的类
      • Class 类
    • 反射示例
      • 获得Class对象的三种方式
      • 反射使用 ——代码
      • 面试题:你知道有几种创建对象的方式吗?
    • 反射优点和缺点
  • 枚举
  • Lambda表达式
    • 概念
    • Lambda表达式的语法
    • 代码

反射

反射定义

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

反射相关的类

在这里插入图片描述

Class 类

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为 一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个 实例(这个Class对象存放在方法区,不在堆里面的).我们通过Java的反射机制应用到这个实例,就 可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类。

反射示例

获得Class对象的三种方式

第一种,使用Class.forName(“类的全路径名”);静态方法。

Class c1 = Class.forName("refelectdemo.Student");

第二种,使用.class 方法

Class c2 = Student.class;

第三种,使用类对象的 getClass() 方法

Student student = new Student();
Class c3 = student.getClass();

完整代码如下:

class Student{//私有属性nameprivate String name = "bit";//公有属性agepublic int age = 18;//不带参数的构造方法public Student(){System.out.println("Student()");}private Student(String name,int age) {this.name = name;this.age = age;System.out.println("Student(String,name)");}private void eat(){System.out.println("i am eat");}public void sleep(){System.out.println("i am pig");}private void function(String str) {System.out.println(str);}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class Test {public static void main1(String[] args) throws ClassNotFoundException{
//        Student student = new Student();//1、获取一个Class对象Class c1 = Class.forName("refelectdemo.Student");Class c2 = Student.class;Student student = new Student();Class c3 = student.getClass();System.out.println(c1.equals(c2));System.out.println(c1.equals(c3));System.out.println(c2.equals(c3));//Class对象  只有1个}
}

反射使用 ——代码

1.通过反射获取Class对象
2.反射私有构造方法

public class ReflectClassDemo {// 创建对象public static void reflectNewInstance() {try {Class c1 = Class.forName("refelectdemo.Student");Student student = (Student)c1.newInstance();System.out.println(student);} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}// 反射私有的构造方法  屏蔽内容为获得公有的构造方法public static void reflectPrivateConstructor() {try {Class c1 = Class.forName("refelectdemo.Student");Constructor constructor = c1.getDeclaredConstructor(String.class,int.class);//私有的本身是封装的,constructor.setAccessible(true);Student student = (Student)constructor.newInstance("bit",19);System.out.println(student);} catch (ClassNotFoundException e) {} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}// 反射所有的,用私有属性来举例public static void reflectPrivateField() {try {Class c1 = Class.forName("refelectdemo.Student");Student student = (Student)c1.newInstance();Field field = c1.getDeclaredField("name");field.setAccessible(true);//student对象的field字段,设置为zhangsan值field.set(student,"zhangsan");System.out.println(student);} catch (ClassNotFoundException e) {} catch (NoSuchFieldException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}// 反射私有方法public static void reflectPrivateMethod() {try {Class c1 = Class.forName("refelectdemo.Student");Student student = (Student)c1.newInstance();//方法名称    方法的参数Method method = c1.getDeclaredMethod("function", String.class);method.setAccessible(true);method.invoke(student,"我是function的参数!");} catch (ClassNotFoundException e) {}  catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}public static void main(String[] args) {//reflectNewInstance();//reflectPrivateConstructor();//reflectPrivateField();reflectPrivateMethod();}}

面试题:你知道有几种创建对象的方式吗?

1、new关键字实例化对象
2、clone()
3、newlnstance()–>Class类的
4、constructor.newInstance()

反射优点和缺点

优点:

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

缺点:

  1. 我们认为反射是一个“自省"的过程,所以在性能上面有性能的问题,一般不建议用在小型程序上,可用到框架当中。
  2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂。

枚举

枚举是在JDK1.5以后引入的。主要用途是:将一组常量组织起来,在这之前表示一组常量通常使用定义常量的方式:

public static final RED = 1; 
public static final GREEN = 2; 
public static final BLACK = 3;

但是常量举例有不好的地方,例如:可能碰巧有个数字1,但是他有可能误会为是RED。现在我们可以直接用枚举来进行组织,这样一来,就拥有了类型,枚举类型。

public enum TestEnum { RED,BLACK,GREEN; }

优点:将常量组织起来统一进行管理
场景:错误状态码,消息类型,颜色的划分,状态机等等…
本质:是 java.lang.Enum 的子类,自己写的枚举类,就算没有显示的继承 Enum ,但是其默认继承了这个类。

不能反射枚举对象
在这里插入图片描述

Lambda表达式

概念

Lambda表达式是Java SE 8中一个重要的新特性。lambda表达式允许你通过表达式来代替功能接口。 lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body),可以是一个表达式或一个代码
块)。 Lambda 表达式(Lambda expression)可以看作是一个匿名函数,基于数学中的λ演算得名,也可称为闭
包(Closure) 。

Lambda表达式的语法

基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
Lambda表达式由三部分组成:

  1. paramaters类似方法中的形参列表,这里的参数是函数式接口里的参数。这里的参数类型可以明确的声明,也可不声明而由JVM隐含的推断。另外当只有一个推断类型时可以省略掉圆括号。
  2. ->:可理解为“被用于”的意思
  3. 方法体:可以是表达式也可以代码块,是函数式接口里方法的实现。代码块可返回一个值或者什么都不反回,这里的代码块块等同于方法的方法体。如果是表达式,也可以返回一个值或者什么都不反回

如果方法体只有一条语句,花括号{}可省略

函数式接口有且只有一个抽象方法。

代码

package lambda;import java.util.Comparator;
import java.util.PriorityQueue;/*** @Author 12629* @Date 2022/4/4 20:19* @Description:*/
//无返回值无参数
@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 Test1 {public static void main1(String[] args) {MoreParameterReturn moreParameterReturn = new MoreParameterReturn(){@Overridepublic int test(int a, int b) {return a+b;}};MoreParameterReturn moreParameterReturn2 = (int a,int b)->{return a+b;};PriorityQueue priorityQueue = new PriorityQueue<>(new Comparator() {@Overridepublic int compare(Integer o1, Integer o2) {return o1-o2;}});PriorityQueue priorityQueue1 = new PriorityQueue<>((o1, o2) -> {return o1-o2;});}
}

一般调用有返回值多参是以下代码实现

MoreParameterReturn moreParameterReturn = new MoreParameterReturn(){@Overridepublic int test(int a, int b) {return a+b;}};

即 一个匿名内部类实现了当前接口,并且重写了这个接口的方法

正则化表达式用如下形式表示,相比之下代码变得更加简洁;

MoreParameterReturn moreParameterReturn2 = (int a,int b)->{return a+b;};

相关内容

热门资讯

拆迁补贴贪污案,开庭后律师紧急... 文/张家豪律师重庆智豪律师事务所高级合伙人 今天想聊一个很特别的职务犯罪案子,这是一起拆迁补偿领域的...
原创 从... 1854年,清文宗咸丰四年,太平天国的国都天京(今南京)发生了一件震动全国的大事。冬官又正丞相陈宗扬...
香港保监局:就风险为本资本制度... 智通财经获悉,媒体此前报道,香港保监局提议一系列新规,拟引导保险资本流向基础设施等资产,这一举措将把...
库里26+6班凯罗21+12 ... 【搜狐体育战报】北京时间12月23日NBA常规赛,主场作战的勇士以120-97击败魔术。库里26分3...
新日股份5.65亿元合同纠纷二... 12月19日,江苏新日电动车股份有限公司(603787.SH,以下简称“新日股份”)发布诉讼进展公告...
庆阳市预防治理未成年人违法犯罪... 12月22日,市委副书记、市委政法委书记王向阳主持召开全市预防治理未成年人违法犯罪工作推进会议,全面...
大庆法援2025年度成绩单 2025年,大庆市各级法律援助机构在市司法局的领导下,以创新机制激活服务效能,以便民服务打通"最后一...
推进房屋体检制度,确保房子更安... 原标题:工人日报社评丨推进房屋体检制度,确保房子更安全更宜居 工人日报评论员 吴迪 房屋体检制度在各...
行政调解丨“问题种子”导致百亩... 齐鲁晚报·齐鲁壹点记者 李文璇 栾海明 一粒种子,关系着千家万户的“粮袋子”和“钱袋子”。2025...
“十五五”时期民间投资发展的法... “十五五”时期是我国基本实现社会主义现代化的关键时期,要落实《民营经济促进法》,从法律和制度上保障平...