再探Java为面试赋能(二)Java基础知识(二)反射机制、Lambda表达式、多态

文章目录

    • 前言
    • 1.4 反射机制
      • 1.4.1 Class对象的获取
      • 1.4.2 Class类的方法
      • 1.4.3 通过反射机制修改只读类的属性
    • 1.5 Lambda表达式
      • 1.5.1 函数式接口
      • 1.5.2 Lambda表达式的使用
    • 1.6 多态
      • 1.6.1 多态的概念
      • 1.6.2 多态的实现条件
      • 1.6.3 重载(Overload)和重写(Override)

前言

往期精选:

再探Java为面试赋能(一)Java基础知识(一)变量初始化顺序、构造方法、clone方法

1.4 反射机制

Java语言的反射机制,是指动态获取类或对象的属性以及方法,从而完成调用功能的一种机制。它主要实现了以下功能:

  • 获取类的访问修饰符、属性、方法以及父类信息。
  • 在运行时根据类名创建对象,还可以调用对象的任意方法。
  • 生成动态代理。

1.4.1 Class对象的获取

在反射机制中,Class类是一个非常重要的类,获取Class对象主要有3种方法:

  • 1)通过className.class获取:
public class Food {static {System.out.println("Food类的静态代码块执行了...");}{System.out.println("Food类的非静态代码块执行了...");}public static void main(String[] args) {Class<Food> aClass = Food.class;System.out.println("className = " + aClass.getName());}
}

程序运行结果:

Food类的静态代码块执行了...
className = test03.Food
  • 2)通过Class.forName()获取:
public class Food {static {System.out.println("Food类的静态代码块执行了...");}{System.out.println("Food类的非静态代码块执行了...");}public static void main(String[] args) throws ClassNotFoundException {Class<?> food = Class.forName("test03.Food");System.out.println("className = " + food.getName());}
}

程序运行结果:

Food类的静态代码块执行了...
className = test03.Food
  • 3)通过Object.getClass()获取:
public class Food {static {System.out.println("Food类的静态代码块执行了...");}{System.out.println("Food类的非静态代码块执行了...");}public static void main(String[] args) {Class<? extends Food> aClass = new Food().getClass();System.out.println("className = " + aClass.getName());}
}

程序运行结果:

Food类的静态代码块执行了...
Food类的非静态代码块执行了...
className = test03.Food

如上面的例子所示,三种方式都可以获得类的Class对象,但也有一些区别:

  • 方法 1)2)执行静态代码块,但不执行非静态代码块;
  • 方法 3)由于创建了对象,因此会执行静态代码块和非静态代码块。

1.4.2 Class类的方法

Class类提供了非常多的方法,常用的有三类:

  • 1)获取类的构造方法

构造方法的封装类为Constructor。

源码:java.lang.Class// 返回类的所有的public构造方法
public Constructor<?>[] getConstructors()
// 返回类的指定参数的public构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
// 返回类的所有构造方法
public Constructor<?>[] getDeclaredConstructors()
// 返回类的指定参数的构造方法
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
  • 2)获取类的成员变量的方法

成员变量的封装类为Field。

源码:java.lang.Class// 返回类的所有public成员变量
public Field[] getFields()
// 返回类的指定名称的public成员变量
public Field getField(String name)
// 返回类的所有成员变量
public Field[] getDeclaredFields()
// 返回类的指定名称的成员变量
public Field getDeclaredField(String name)
  • 3)获取类的方法

方法的封装类为Method。

源码:java.lang.Class// 返回类的所有public方法
public Method[] getMethods()
// 返回类的指定名称和参数的public方法
public Method getMethod(String name, Class<?>... parameterTypes)
// 返回类的所有方法
public Method[] getDeclaredMethods()
// 返回类的指定名称和参数的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

1.4.3 通过反射机制修改只读类的属性

有如下代码:

public class ReadOnlyClass {private Integer age = 20;public Integer getAge() {return age;}
}

在这个类中,age属性被修饰为private,且只提供了getter方法,而没有提供setter方法,因此这个类型是一个只读的类,无法通过常规方法修改age属性。

但通过Java的反射机制就可以修改age属性。例如:

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {ReadOnlyClass roc = new ReadOnlyClass();System.out.println("修改前age = " + roc.getAge());Class<ReadOnlyClass> aClass = ReadOnlyClass.class;Field field = aClass.getDeclaredField("age");field.setAccessible(true);// 修改roc对象的age属性field.set(roc, 30);System.out.println("修改后age = " + roc.getAge());
}

执行结果:

修改前age = 20
修改后age = 30

1.5 Lambda表达式

简单来说,Lambda表达式就是对匿名内部类的简写。它的基本语法是:

<函数式接口> <变量名> = (参数1, 参数2, ...) -> {// 方法体
}

1.5.1 函数式接口

函数式接口就是一个有且仅有一个抽象方法的接口。

例如Runnable接口就是一个函数式接口:

源码:java.lang.Runnable@FunctionalInterface
public interface Runnable {public abstract void run();
}

可见,Runnable接口中只包含一个抽象的run()方法,并且在接口上标注了一个@FuncationInterface注解,此注解就是 Java 8 新增的注解,用来标识一个函数式接口。

想要自定义一个函数式接口也非常简单,只需要在接口中定义一个抽象方法,然后在接口上标记@FunctionalInterface注解。

当然,该注解也可以不标记,只是说标记了该注解,编辑器会自动检测自定义的函数式接口是否有问题。例如:

1.5.2 Lambda表达式的使用

下面是一个自定义的函数式接口,定义了一个有参数有返回值的sum()方法:

@FunctionalInterface
public interface MyInterface {public abstract int sum(int a, int b);
}

使用Lambda表达式调用该方法:

public static void main(String[] args) {// 使用匿名内部类方式MyInterface myInterface = new MyInterface() {@Overridepublic int sum(int a, int b) {return a+b;}};int sum = myInterface.sum(5, 10);System.out.println("匿名内部类方式 sum = " + sum);// 使用Lambda表达式MyInterface myi = (a, b) -> a+b;int sum1 = myi.sum(2, 8);System.out.println("Lambda表达式方式 sum1 = " + sum1);
}

执行结果:

匿名内部类方式 sum = 15
Lambda表达式方式 sum1 = 15

可见,使用Lambda表达式后,代码变得更加简介。

Lambda表达式还有更多编写规则如下:

  • 1)参数只需要参数名称,不需要参数类型,编译器会自动推断类型。如示例中:(a, b)
  • 2)如果参数只有一个,可以省略小括号(),没有参数或者参数多于一个,不能省略小括号。
  • 3)方法体只有一行代码时,可以省略中括号{}
  • 4)方法体只有一行代码时,且有返回值时,可以省略return关键字。如示例中:-> a+b

1.6 多态

1.6.1 多态的概念

多态是面向对象编程中的一个重要概念,它允许不同类型的对象对同一方法进行不同的实现。

具体来说,多态是指通过父类的引用变量来指向子类的对象,从而实现对不同对象的统一操作。

例如,猫和狗都是动物,都有“吃”这个共同行为,具体表现在狗身上可能是啃骨头,表现在猫身上可能是吃猫粮。这就是多态的表现,即同一件事情,发生在不同的对象身上,就会产生不同的结果。

1.6.2 多态的实现条件

在Java中,要实现多态性,就必须满足以下条件:

  • 1)继承关系
  • 2)方法重写
  • 3)父类引用指向子类对象

例如,首先定义一个父类Animal,该类有一个eat()方法:

public class Animal {public void eat() {System.out.println("动物吃东西...");}
}

再定义两个子类Dog和Cat,均继承父类Animal,并重写其eat()方法:

public class Dog extends Animal {// 1.继承关系// 2.方法重写@Overridepublic void eat() {System.out.println("狗啃骨头...");}
}
public class Cat extends Animal {// 1.继承关系// 2.方法重写@Overridepublic void eat() {System.out.println("猫吃猫粮...");}
}

最后编写测试方法:

public class Main {public static void main(String[] args) {// 3.父类引用指向子类对象Animal dog = new Dog();Animal cat = new Cat();dog.eat();cat.eat();}
}

执行结果:

狗啃骨头...
猫吃猫粮...

1.6.3 重载(Overload)和重写(Override)

Java中多态的实现条件之一是方法重写,是指子类重新定义和实现从父类继承而来的方法,以改变方法的行为,提供自己特定的实现。

方法重写必须遵循一些规则:

  • 1)子类重写方法的名称、参数列表(包括数量、类型、顺序)和返回值类型都必须与父类中被重写的方法相同。
  • 2)重写方法的访问修饰符的权限不能低于父类方法的权限。例如,父类方法被public修饰,则子类中重写方法就不能声明为protected
  • 3)重写方法不能抛出比父类方法更多或更宽泛的异常,重写方法可以抛出相同的异常或更具体的异常,或者不抛出异常。
  • 4)重写方法可以通过super()函数调用父类方法的逻辑。

重载是指在一个类中定义了多个同名的方法。 它也必须遵循一些规则:

  • 1)重载的方法必须定义在一个类中,它们的名称必须相同。
  • 2)重载的方法的参数列表必须不同,可以通过参数的个数、类型、顺序的不同来进行区分。
  • 3)重载的方法的返回值类型可以相同也可以不同。

总结一下,重载和重写的区别:

  • 1)定义位置。重载方法定义在同一个类中,而重写方法定义在父类和子类之间。
  • 2)方法签名。重载方法具有相同的名称,但方法签名(参数类型、个数或顺序)不同,而重写方法具有相同的名称和方法签名。
  • 3)调用时机。重载方法是根据方法签名的不同进行静态绑定,在编译时就确定,而重写方法是根据对象的实际类型进行动态绑定,要在运行时确定。

本节完,更多内容请查阅分类专栏:再探Java为面试赋能

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析(已完结)
  • MyBatis3源码深度解析(已完结)
  • Redis从入门到精通(持续更新中…)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/801589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大数据之搭建Hive组件

声明&#xff1a;所有软件自行下载&#xff0c;并存放到统一目录中 1.Hive组件的安装配置 1.1实验环境 服务器集群3 个以上节点&#xff0c;节点间网络互通&#xff0c;各节点最低配置&#xff1a;双核 CPU、8GB 内存、100G 硬盘运行环境CentOS 7.4服务和组件完成前面章节实验…

Java基础笔记(一)

一、面向对象高级基础 1.Java的动态绑定机制 public class DynamicBinding {public static void main(String[] args) {//a 的编译类型 A, 运行类型 BA a new B();//向上转型System.out.println(a.sum());//40 子类sum()注释后-> 30System.out.println(a.sum1());//30 子类…

android-自定义TextView在文字内容末尾添加图片icon、可以添加间距

样式示意图 自定义属性 style.xml <declare-styleable name"IconLabelTextView"><attr name"iconSrc" format"reference"/><attr name"iconPaddingStart" format"dimension"/><attr name"iconPad…

访问网站显示不安全是什么原因?怎么解决?

访问网站时显示“不安全”&#xff0c;主要原因以及解决办法&#xff1a; 1.没用HTTPS加密&#xff1a;网站还在用老的HTTP协议&#xff0c;数据传输没加密&#xff0c;容易被人偷看或篡改。解决办法是网站管理员启用HTTPS&#xff0c;也就是给网站装个“SSL证书”。这个是最常…

模块十三 异常_Object

回顾与重点 模块十二回顾 权限修饰符&#xff1a; public → protected → 默认 → private a. 构造一般用public&#xff1a;便于new对象 b. 成员方法一般用public&#xff1a;便于调用 c. 属性一般用private&#xff1a;封装思想 final&#xff1a;最终的 a. 修饰类&#x…

k8s_入门_kubelet安装

安装 在大致了解了一些k8s的基本概念之后&#xff0c;我们实际部署一个k8s集群&#xff0c;做进一步的了解 1. 裸机安装 采用三台机器&#xff0c;一台机器为Master&#xff08;控制面板组件&#xff09;两台机器为Node&#xff08;工作节点&#xff09; 机器的准备有两种方式…

前端开发之el-table(vue2中)固定列fixed滚动条被固定列盖住

固定列fixed滚动条被固定列盖住 效果图前言解决方案 效果图 前言 在使用fixed固定列的时候会出现滚动条被盖住的情况 解决方案 改变el-table固定列的计算高度即可 .el-table {.el-table__fixed-right,.el-table__fixed {height:auto !important;bottom:15px !important;}}

数据结构(七)——查找的基本概念

七、查找 7.1 查找的基本概念 7.1.1 基本概念 查找 —— 在数据集合中寻找满⾜某种条件的数据元素的过程称为查找 查找表&#xff08;查找结构&#xff09;—— ⽤于查找的数据集合称为查找表&#xff0c;它由同⼀类型的数据元素&#xff08;或记录&#xff09;组成 关键字 …

Golang | Leetcode Golang题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; func fourSum(nums []int, target int) (quadruplets [][]int) {sort.Ints(nums)n : len(nums)for i : 0; i < n-3 && nums[i]nums[i1]nums[i2]nums[i3] < target; i {if i > 0 && nums[i] nums[i-1] || nums[i]…

数字化智慧养老:引领老年人融入科技时代新生活

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 人类社会已经步入了一个全新的数字时代。在这个时代&#xff0c;互联网、大数据、人工智…

PDF锐化

PDF Shaper Ultimate(pdf转图片) 编辑->添加文件->选中一个要处理的pdf 操作->转换->PDF转为图片 ComicEnhancerPro设置(把图片锐化) PDF Shaper Ultimate(图片转pdf) 编辑-添加图片->选中所有锐化处理后的图片 转换->图片转为pdf&#xff08;会把所有图…

全国火情预报卫星遥感应用方案

一、引言 火情预报应急卫星遥感解决方案是一种利用卫星遥感技术进行火灾预警和应急响应的方法。该方案通过实时监测和分析森林、草原等地区的火情信息&#xff0c;为火灾预警和应急响应提供科学依据&#xff0c;有效减少火灾造成的损失。本技术文档将介绍火情预报应急卫…

Java | Leetcode Java题解之第18题四数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> fourSum(int[] nums, int target) {List<List<Integer>> quadruplets new ArrayList<List<Integer>>();if (nums null || nums.length < 4) {return…

el-cascader的懒加载模式怎么设置默认值

点击修改会跳出一个dialog&#xff0c;dialog需要显示信息&#xff0c;其中地址使用el-cascader标签并使用懒加载实现&#xff0c;地址数据都是从后台获取&#xff0c;如果直接使用v-model绑定默认值&#xff0c;会不显示。 解决方法1&#xff1a; <el-cascader class&quo…

React - 请你说一说setState是同步的还是异步的

难度级别:中高级及以上 提问概率:70% 在React项目中,使用setState可以更新状态数据,而不能直接使用为this.state赋值的方式。而为了避免重复更新state数据,React首先将state添加到状态队列中,此时我们可以通过shouldComponentUpdate这个钩…

Python编程启航:大学生如何用代码编织未来

开篇 掌握Python&#xff0c;打开编程世界的大门&#xff01;作为一名大学生&#xff0c;你是否渴望在编程的海洋中遨游&#xff0c;用代码编织未来&#xff1f; &#x1f31f;&#x1f680;现在就跟随我一起&#xff0c;探索Python编程的奇妙之旅&#xff0c;解锁学习技巧、…

数据库——实验6 视图的创建与使用

1. 视图的定义 视图是根据需要以一个表或多个表为基础&#xff0c;选择满足一定条件的行或列数据的静态定义。它是一种逻辑对象&#xff0c;是一种虚拟表。视图并不生成行或列的永久副本&#xff0c;并不占用存储空 间&#xff0c;也就是说&#xff0c;视图就是保存在数据库中…

加州大学欧文分校英语基础语法专项课程03:Simple Past Tense 学习笔记(完结)

Learn English: Beginning Grammar Specialization Specialization Certificate course 3&#xff1a; Simple Past Tense Course Certificate 本文是学习 https://www.coursera.org/learn/simple-past-tense 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。…

函数重载和引用【C++】

文章目录 函数重载什么是函数重载&#xff1f;函数重载的作用使用函数重载的注意点为什么C可以函数重载&#xff0c;C语言不行&#xff1f; 引用什么是引用&#xff1f;引用的语法引用的特点引用的使用场景引用的底层实现传参时传引用和传值的效率引用和指针的区别 函数重载 什…

OpenHarmony实战:物联网解决方案之芯海cst85芯片移植案例

本文介绍基于芯海cst85芯片的cst85_wblink开发板移植OpenHarmony LiteOS-M轻量系统的移植案例。 开发了Wi-Fi连接样例和XTS测试样例&#xff0c;同时实现了wifi_lite, lwip, startup, utils, xts, hdf等部件基于OpenHarmony LiteOS-M内核的适配。 移植架构上采用Board和Soc分…