JAVA 学习 面试(十)枚举、注解、基本原则

枚举
  • 默认继承 java.lang.Enum 类,不能继承其他父类,并自动添加了values(获取枚举类中的所有枚举值)和valueOf(获取对应的枚举类型)方法, java.lang.Enum 类实现了 java.lang.Serializable 和 java.lang.Comparable 接口
  • enum默认使用 final 修饰,不能派生子类,构造器默认使用 private 修饰,且只能使用 private 修饰
  • 枚举类所有实例必须在第一行给出,默认添加 public static final 修饰,用内部类实现,该内部类继承了枚举类。所有枚举常量都通过静态代码块来进行初始化
    java.util.EnumSet:保证集合中的元素不重复java.util.EnumMap:EnumMap中的 key是enum类型,而value则可以是任意类型

注意:

  1. 枚举类型对象之间的值比较可以使用“==”直接来比较值是否相等的,因为枚举类Enum已经重写了equals方法

  2. 每个枚举都定义了两个属性,name和ordinal,name表示我们定义的枚举常量的名称,如FRIDAY、TUESDAY,而ordinal是一个顺序号,根据定义的顺序分别赋予一个整形值,从0开始。在枚举常量初始化时,会自动为初始化这两个字段,设置相应的值,在构造方法中添加了两个参数。

  3. name和ordinal属性都是final的,clone、readObject、writeObject这三个方法也是final的,这三个方法和枚举通过静态代码块来一起进行初始化。

  4. clone、readObject、writeObject三个方法保证了枚举类型的不可变性(即不能通过克隆,不能通过序列化和反序列化来复制枚举),保证枚举常量是单例的。注解是绑定到程序源代码元素的元数据,对运行代码的操作没有影响

注解

注解是一种标记在 Java 类、方法、字段和其他程序元素上的特殊标签,它提供了一种安全的类似注释的机制,用来将任何的信息或元数据(metadata)与程序元素(类、方法、成员变量等)进行关联。

注解分为三类:

  1. 内置注解:这些注解用于特殊的用途,如告诉编译器生成警告或错误,控制序列化过程等。

    1. @Override 注解用于告诉编译器,希望重写(覆盖)父类中的方法。如果父类中不存在与该方法签名匹配的方法,编译器会产生一个错误。
    2. @Deprecated 注解用于标记方法、类或字段已过时,不推荐使用。编译器会发出警告,提示开发者尽量避免使用被标记为过时的元素。
    3. @SuppressWarnings 注解用于告诉编译器忽略特定类型的警告。这对于处理旧代码或集成第三方库时非常有用。
    @SuppressWarnings("unchecked")
    public List<String> getItems() {// 忽略类型未检查的警告return new ArrayList();
    }
    
  2. 自定义注解:可以用来添加程序的元数据,或者用于特定的用途,例如测试框架、依赖注入等

    // 定义自定义注解
    public @interface MyAnnotation {String value() default "default value"; // 定义一个元素int number() default 0; // 定义另一个元素
    }
    @MyAnnotation(value = "Custom Value", number = 42)
    public class MyClass {// 类的内容
    }
    Class<?> clazz = MyClass.class;
    MyAnnotation annotation = clazz.getAnnotation(MyAnnotation.class);if (annotation != null) {String value = annotation.value();int number = annotation.number();System.out.println("Value: " + value);System.out.println("Number: " + number);
    } else {System.out.println("MyAnnotation not found.");
    }
    // 注解的元素可以是基本数据类型、字符串、枚举类型、注解类型或以上类型的数组
    public @interface MyAnnotation {int value() default 0;String name() default "John";Color color() default Color.RED;String[] tags() default {};Class<?>[] classes() default {};MyOtherAnnotation otherAnnotation() default @MyOtherAnnotation;
    }
    
  3. 元注解:是用于定义注解的注解,包括@Retention、@Target、@Inherited、@Documented 等6种

@Retention:指定其所修饰的注解的保留策略
@Document:该注解是一个标记注解,用于指示一个注解将被文档化
@Target:用来限制注解的使用范围
@Inherited:该注解使父类的注解能被其子类继承
@Target(ElementType.TYPE) // 该注解可以用在类上
@Retention(RetentionPolicy.RUNTIME) // 注解信息会保留到运行时
public @interface ExcellentStudent {
}
@ExcellentStudent // 我们在 Student 类上应用 @ExcellentStudent 注解
public class Student {private String name;private int age;private double gpa;// 构造方法和其他方法省略
}
// 使用反射来查找并识别优秀学生
public class Main {public static void main(String[] args) {// 获取 Student 类的 Class 对象Class<?> clazz = Student.class;// 检查类上是否有 ExcellentStudent 注解if (clazz.isAnnotationPresent(ExcellentStudent.class)) {// 如果有,打印学生信息System.out.println("优秀学生信息:");Student student = new Student("Alice", 20, 4.0);System.out.println(student);} else {System.out.println("没有优秀学生信息。");}}
}

注意:

  • 注解本身不影响程序的运行,只提供了元数据。

  • 注解在编译时可以被处理,也可以在运行时被处理,具体取决于注解的类型和用途。

  • 自定义注解需要使用 @Retention 指定它的保留策略,通常是 RUNTIME,以便在运行时读取注解信息。

  • 注解的元素名称通常为 value,但可以自定义其他名称。

Retention– 定义该注解的生命周期

RetentionPolicy.SOURCE:在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解
RetentionPolicy.CLASS:在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
RetentionPolicy.RUNTIME:始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式

Target –注解用于什么地方

  1. ElementType.CONSTRUCTOR:用于描述构造器
  2. ElementType.FIELD:成员变量、对象、属性(包括enum实例)
  3. ElementType.LOCAL_VARIABLE:用于描述局部变量
  4. ElementType.METHOD:用于描述方法

@Override -标记方法是否覆盖超类中声明的元素。如果它无法正确覆盖该方法,编译器将发出错误
@Deprecated - 表示该元素已弃用且不应使用。如果程序使用标有此批注的方法,类或字段,编译器将发出警告
@SuppressWarnings - 告诉编译器禁止特定警告。在与泛型出现之前编写的遗留代码接口时最常用的
@FunctionalInterface - 在Java 8中引入,表明类型声明是一个功能接口,可以使用Lambda Expression提供其实现
注解方法声明返回类型必须是基本类型,String,Class,Enum或数组类型之一。否则,编译器将抛出错误
@Target注解可以限制应用注解的元素

基本原则
  • **单一职责:**一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。

    一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于将这些职责耦合在一起,当其中一个职责变化时,可能会影响其他职责的运作。
    
  • 开闭原则:面向修改关闭,面向扩展开放

    设计一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为。
    比如我们的程序员分为Java程序员、C#程序员、C++程序员、PHP程序员、前端程序员等,而他们要做的都是去打代码,而具体如何打代码是根据不同语言的程序员来决定的,我们可以将程序员打代码这一个行为抽象成一个统一的接口或是抽象类,而具体哪个程序员使用什么语言怎么编程,是自己在负责,不需要其他程序员干涉
    
  • 李氏替换:子类可以替换父类

    // 我们不需要再继承自Coder了
    public abstract class Coder {public void coding() {System.out.println("我会打代码");}class JavaCoder extends Coder{public void game(){System.out.println("艾欧尼亚最强王者已上号");}/*** 这里我们对父类的行为进行了重写,现在它不再具备父类原本的能力了*/public void coding() {System.out.println("我寒窗苦读十六年,到最后还不如培训班三个月出来的程序员");}}
    }
    
  • 依赖倒置:面向接口编程

    代码要依赖于抽象的类,而不要依赖于具体的类;要针对接口或抽象类编程,而不是针对具体类编程
    public class Main {public static void main(String[] args) {UserController controller = new UserController();}interface UserMapper {//接口中只做CRUD方法定义}static class UserMapperImpl implements UserMapper {//实现类完成CRUD具体实现}interface UserService {//业务代码定义....}static class UserServiceImpl implements UserService {@Resource   //现在由Spring来为我们选择一个指定的实现类,然后注入,而不是由我们在类中硬编码进行指定UserMapper mapper;//业务代码具体实现}static class UserController {@ResourceUserService service;   //直接使用接口,就算你改实现,我也不需要再修改代码了//业务代码....}
    }
    
  • 聚合/组合优于继承

    class A { // 如果有一天,由于业务的更改,我们的数据库连接操作,不再由A来负责,而是由新来的C去负责,那么这个时候,我们就不得不将需要复用A中方法的子类全部进行修改public void connectDatabase(){System.out.println("我是连接数据库操作!");}
    }class B {   //不进行继承,而是在用的时候给我一个A,当然也可以抽象成一个接口,更加灵活public void test(A a){System.out.println("我是B的方法,我也需要连接数据库!");a.connectDatabase();   //在通过传入的对象A去执行}
    }// to
    class A {public void connectDatabase(){System.out.println("我是连接数据库操作!");}
    }class B {   //不进行继承,而是在用的时候给我一个A,当然也可以抽象成一个接口,更加灵活public void test(A a){System.out.println("我是B的方法,我也需要连接数据库!");a.connectDatabase();   //在通过传入的对象A去执行}
    }
    
  • 接口隔离:接口要小而专,而不是大而全

    客户端不应该依赖那些它不需要的接口。注意,在该定义中的接口指的是所定义的方法。
    一旦一个接口太大,则需要将它分割成一些更细小的接*,使用该接口的客户端仅需知道与之相关的方法即可。将一组相关的操作定义在一个接口中,且在满足高内聚的前提下,接口中的方法越少越好。
    
  • 迪米特法则:最小知识原则

    1. 在类的划分上,应当尽量创建松耦合的类,类之间的耦合度越低,就越有利于复用,一个处在松耦合中的类一旦被修改,不会对关联的类造成太大波及。
    2. 在类的结构设计上,每一个类都应当尽量降低其成员变量和成员函数的访问权限。
    3. 在类的设计上,只要有可能,一个类型应当设计成不变类;
    4. 在对其他类的引用上,一个对象对其他对象的引用应当降到最低。
    
    public class Main {public static void main(String[] args) throws IOException {Socket socket = new Socket("localhost", 8080);   //假设我们当前的程序需要进行网络通信Test test = new Test();test.test(socket);   //现在需要执行test方法来做一些事情}static class Test {/*** 比如test方法需要得到我们当前Socket连接的本地地址*/public void test(Socket socket){System.out.println("IP地址:"+socket.getLocalAddress());}}
    }
    // to
    static class Test {public void test(String str){   //一个字符串就能搞定,就没必要丢整个对象进来System.out.println("IP地址:"+str);}}
    

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

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

相关文章

翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一 GPT-4 Vision 的 7 个实际用例 Pre-requisites:先决条件&#xff1a; 订阅 ChatGPT Plus 以访问 GPT-4 Vision。如果您不熟悉 Streamlit&#xff0c;请按照安装步骤操作。 1. 绘制您的应…

C++面试:二叉树和红黑树

目录 二叉树 1. 二叉树的定义 2. 二叉树的遍历 3. 二叉树的应用 4. 实现细节 5. C中的实现 面试准备 红黑树 红黑树的原理 红黑树的用途 示例代码 面试准备 1. 红黑树的工作原理及其规则 2. 红黑树的优势及与其他二叉搜索树&#xff08;如AVL树&#xff09;的比较…

尚无忧球馆助教系统源码,助教小程序源码,助教源码,陪练系统源码

特色功能&#xff1a; 不同助教服务类型选择 助教申请&#xff0c;接单&#xff0c;陪练师入住&#xff0c;赚取外快 线下场馆入住 设置自己服务 城市代理 分销商入住 优惠券 技术栈&#xff1a;前端uniapp后端thinkphp 独立全开源

.NET高级面试指南专题一【委托和事件】

在C#中&#xff0c;委托&#xff08;Delegate&#xff09;和事件&#xff08;Event&#xff09;是两个重要的概念&#xff0c;它们通常用于实现事件驱动编程和回调机制。 委托定义&#xff1a; 委托是一个类&#xff0c;它定义了方法的类型&#xff0c;使得可以将方法当作另一个…

pyqt添加菜单栏

参考&#xff1a; https://blog.csdn.net/seniorwizard/article/details/109820641 import sys from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu, QAction, QPlainTextEdi…

HarmonyOS鸿蒙ArkTS,封装http网络请求

HarmonyOS鸿蒙ArkTS&#xff0c;封装http网络请求 前提&#xff1a; 要想使用http请求&#xff0c;系统必须要具备ohos.permission.INTERNET权限&#xff0c;在model.json5文件中的module模块下添加如下请求权限&#xff1a; 在module.json5文件中 配置 "requestPermi…

踩坑(6)Redisson调用unlockAsync方法释放锁失败

问题描述 通过redisson的lockAsync异步方法获取到锁之后&#xff0c;再业务执行完成后调用lock.unlockAsync()无法释放当前锁&#xff0c;导致后续的方法被阻塞 public void asyncLock() {RLock lock redissonClient.getLock("asyncLock");RFuture<Void> fut…

LeetCode 热题 100 | 矩阵

目录 1 73. 矩阵置零 2 54. 螺旋矩阵 3 48. 旋转图像 4 240. 搜索二维矩阵 II 菜鸟做题第二周&#xff0c;语言是 C 1 73. 矩阵置零 解题思路&#xff1a; 遍历矩阵&#xff0c;寻找等于 0 的元素&#xff0c;记录对应的行和列将被记录的行的元素全部置 0将被记录的…

k8s 进阶实战笔记 | Scheduler 调度策略总结

文章目录 Scheduler 调度策略总结调度原理和过程调度策略nodeSelect亲和性和反亲和性NodeAffinify亲和验证PodAffinity 亲和验证PodAntiAffinity 反亲和验证污点与容忍跳过 Scheduler 调度策略 调度策略场景总结 Scheduler 调度策略总结 调度原理和过程 Scheduler 一直监听着…

k8s Ingress部署应用

Deployment(部署) Deployment处于master节点&#xff0c;master会选择合适的work节点创建Container Container会被包含在Pod中 通过k8s部署一个nginx kubectl create deployment my-nginx --imagenginx创建一个tomcat 镜像 创建一个tomcat-svc.yaml文件 创建service类型…

【心得】java JNDI配合RMI实现注入个人笔记

目录 JNDI RMI 基本概念 RMI 基本逻辑 恶意利用 JNDI注入RMI实现攻击 JNDI Java Naming and Directory Interface Java 命令和目录接口 让配置参数 和 代码 解耦的规范或者思想 低耦合 高内聚 Name 命名 java对象 通过 命名 绑定到 容器环境 java对象和一个特定的…

Java技术栈 —— Kafka入门(一)

Java技术栈 —— Kafka入门&#xff08;一&#xff09; 一、什么是Kafka&#xff1f;二、如何安装Kafka&#xff1f; 一、什么是Kafka&#xff1f; Kafka是一种消息队列&#xff0c;通过订阅-发布机制可以实现解耦合&#xff0c;用异步处理代替同步处理[1] 。&#xff08;理解这…

REVIT二次开发万能刷

将这两个参数赋予其他参数 步骤2 将来做个可以调控的版本 using System; using System.Collections.Generic; using System.Lin

如何把word檔案自動化

1.安裝 pip install jojo-office ( 安裝這個) 2.讀取表格內容與文章內容&#xff0c;範例如下 import office from docx import Document replace{“{user_name}”:“陳彥甫”, “{tele}”:“0912882881”} docDocument(“template.docx”) tabledoc.tables[0] print(“ii:”…

《Python 简易速速上手小册》第7章:高级 Python 编程(基于最新版 Python3.12 编写)

注意&#xff1a;本《Python 简易速速上手小册》 核心目的在于让零基础新手「快速构建 Python 知识体系」 文章目录 <mark >注意&#xff1a;本《Python 简易速速上手小册》<mark >核心目的在于让零基础新手「快速构建 Python 知识体系」 7.1 装饰器和闭包7.1.1 装…

华为机考入门python3--(4)牛客4-字符串分隔

分类&#xff1a;字符串 知识点&#xff1a; 复制符号* 复制3个0 0*3 000 字符串截取 截取第i位到j-1位 str[i:j] 题目来自【牛客】 input_str input().strip()# 先补齐 if len(input_str) % 8 ! 0: input_str 0 * (8 - len(input_str) % 8) # 每8个分 out…

R语言【taxlist】——indended_list():将层级结构输出为缩进列表

Package taxlist version 0.2.4 Description 将 taxlist 对象打印分类层次结构&#xff08;等级和父子关系&#xff09;输出为缩进列表。 Usage indented_list(object, ...)## S4 method for signature taxlist indented_list(object,filter,keep_children TRUE,keep_parent…

uniapp微信小程序-请求二次封装(直接可用)

一、请求封装优点 代码重用性&#xff1a;通过封装请求&#xff0c;你可以在整个项目中重用相同的请求逻辑。这样一来&#xff0c;如果 API 发生变化或者需要进行优化&#xff0c;你只需在一个地方修改代码&#xff0c;而不是在每个使用这个请求的地方都进行修改。 可维护性&a…

JAVA学习笔记三

1.java执行流程分析 2.什么是编译 javac Hello.java 1.有了java源文件&#xff0c;通过编译器将其编译成JVM可以识别的字节码文件 2.在该源文件目录下&#xff0c;通过javac编译工具对Hello.java文件进行编译 3.如果程序没有错误&#xff0c;没有任何提示&#xff0c;但在…

【Spring连载】使用Spring访问 Apache Kafka(十八)----非阻塞重试

【Spring连载】使用Spring访问 Apache Kafka&#xff08;十八&#xff09;----非阻塞重试Non-Blocking Retries 一、这种模式是如何运作的How The Pattern Works二、回退延迟精度Back Off Delay Precision概述和保证Overview and Guarantees 三、配置Configuration四、Programm…