写点什么

《面试 1v1》java 注解

作者:JavaPub
  • 2023-07-13
    北京
  • 本文字数:2569 字

    阅读完需:约 8 分钟

《面试1v1》java注解

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。


《面试1v1》 连载中...



面试官: 接下来,聊聊 Java 的注解,它们到底有什么用?


候选人: 注解的用处主要三个:第一个,编译期使用。比如 @Override 确保你正确重写了方法,@Deprecated 表示这个方法以后可能会删掉。第二个,运行期使用。很多框架通过反射来读注解,根据注解改变程序的行为。像 Spring 的 @Autowired 就是运行期读取的。第三个, build tool 用。很多构建工具会在构建代码时扫描和读取注解,根据注解做相应的操作。JUnit 的 @Test 就是告诉测试运行器哪些是测试方法。


面试官:注解和注释有什么区别吧?


候选人: 注释是写给人看的,注解是写给机器看的。注释不会对程序产生任何影响,注解会影响程序的编译、运行。注释是// 或者/* */,注解是 @打头的。


面试官:举个自定义注解的例子?


候选人: 这里有个自定义注解的示例:


//自定义注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)  public @interface MyAnno {    String name() default "Hello"; }
//使用注解public class MyClass { @MyAnno(name = "World") public void sayHello() { System.out.println("Hello World"); }}
//读取注解MyAnno anno = MyClass.class.getMethod("sayHello").getAnnotation(MyAnno.class); String name = anno.name(); // name = "World"
复制代码


面试官:说说 Spring 中常见的注解?


候选人: Spring 中超级常用的注解有:@Component:把类标记为 Spring 的组件,用于组件扫描。@Autowired:自动装配成员变量、构造方法和方法参数。@Service:标记业务层组件。@Controller:标记控制层组件。 @Repository:标记数据访问组件。 @RequestMapping:映射请求 URL 到控制器处理方法。@Configuration:标记配置类。 @Enable*:开启某个功能,比如 @EnableTransactionManagement 开启事务功能。这些注解大大简化了 Spring 的配置,真的很常用!


面试官:SpringBoot 中常见的注解也说一下?


候选人: SpringBoot 中常用的注解有:@SpringBootApplication:标记这个类是 SpringBoot 的主配置类。@Configuration:标记这个类是配置类。@EnableAutoConfiguration:开启 SpringBoot 的自动配置。@ComponentScan:开启组件扫描,找出应用相关的 bean。@RestController:标记这个控制器直接返回 JSON 或 XML 数据。@RequestMapping:映射请求 URL。 @Autowired:自动装配 bean。 @Repository、@Service、@Controller:标记 DAO、Service、Controller 层的 bean。这些注解的作用和 Spring 差不多,只是在 SpringBoot 中简单了很多,几乎都可以不写 XML 配置了。


面试官:最后,AOP 中的注解呢?


候选人: AOP 中最重要的注解有: @Aspect:标记一个切面。 @Pointcut:定义一个切点,可以是一个规则表达式,和 @Before 等注解搭配使用。@Before:前置通知,在目标方法调用前执行。@AfterReturning:后置通知,在目标方法正常返回后执行。


@AfterThrowing:异常通知,在目标方法抛出异常后执行。 @After:最终通知,无论目标方法是否正常完成都会执行。 @Around:环绕通知,手动控制目标方法调用时机。这些 AOP 注解通过在方法上标记,就可以实现方法的切入、替换等,真正做到面向切面编程。


面试官:自定义注解需要什么?


候选人: 自定义注解需要两个注解:@Target 定义可以用于什么地方(方法、类等),@Retention 定义注解的生命周期(编译期、运行期、源码)。然后使用 @interface 自定义注解,可以添加属性,默认值等。


面试官:注解的生命周期有几种?


候选人: 注解生命周期有 3 种:源码阶段:@Retention(RetentionPolicy.SOURCE),编译后失效。编译阶段:@Retention(RetentionPolicy.CLASS),编译后存在于字节码文件中,运行时无法获得。运行阶段:@Retention(RetentionPolicy.RUNTIME),编译后存在于字节码文件中,运行时可以通过反射获取。大部分自定义注解都使用 RUNTIME,以方便通过反射来读取和使用注解信息。


面试官:Enum 中的注解呢?


候选人: @Retention(RetentionPolicy.SOURCE)只存在于源码,编译后失效。@Retention(RetentionPolicy.RUNTIME)会保留至运行时,可以通过反射读取。所以 Enum 中的注解一般使用 RUNTIME。枚举例子:


@Retention(RetentionPolicy.RUNTIME)@interface Color {    ColorType value();}
public enum ColorType { @Color(ColorType.RED) RED, @Color(ColorType.GREEN) GREEN, @Color(ColorType.BLUE) BLUE}
复制代码


面试官:注解在哪些地方可以使用?


候选人: 注解可以放在:类、接口、枚举上字段、方法上方法的参数上局部变量上构造器上包上所以注解的 @Target 有:ElementType.TYPE:接口、类、枚举、注解 ElementType.FIELD:字段、枚举的常量 ElementType.METHOD:方法 ElementType.PARAMETER:方法参数 ElementType.CONSTRUCTOR:构造器 ElementType.LOCAL_VARIABLE:局部变量 ElementType.PACKAGE:包等等。


面试官:运行时注解的使用场景?


候选人: 运行时注解主要有两大使用场景:


  1. 框架使用:很多框架使用运行时注解读取注解信息,调用相应的处理逻辑。如 Spring 使用 @Autowired、@PostConstruct 等实现依赖注入和初始化方法调用。

  2. 自定义注解:我们可以自定义运行时注解,在程序运行时通过反射读取注解,执行相应逻辑。比如:


@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {}
public class Main { @MyAnnotation public void doSomething() { // ... }}
复制代码


然后通过反射调用:


Method m = Main.class.getMethod("doSomething"); MyAnnotation anno = m.getAnnotation(MyAnnotation.class);//执行相关逻辑
复制代码


面试官:最后一个问题,注解有哪些限制?


候选人: 注解有以下几个限制:


  1. 注解不能继承其他注解或接口。

  2. 注解只有成员变量,没有方法。

  3. 注解中的成员变量只能是基本类型、String、Enum、Annotation 等,不能是对象。

  4. 如果注解有默认值,在使用注解时可以忽略该值。

  5. 同一个地方不能同时存在两个同名注解。

  6. 注解不能作用于变量、类的私有成员上。

  7. 注解不会继承,子类或者实现类无法继承父类或者接口的注解。



最近我在更新《面试 1v1》系列文章,主要以场景化的方式,讲解我们在面试中遇到的问题,致力于让每一位工程师拿到自己心仪的 offer,感兴趣可以关注 JavaPub 追更!



《面试1v1》 连载中...



🎁目录合集:


Gitee:https://gitee.com/rodert/JavaPub


GitHub:https://github.com/Rodert/JavaPub


http://javapub.net.cn


发布于: 刚刚阅读数: 5
用户头像

JavaPub

关注

原创技术公众号:JavaPub 2018-12-02 加入

原创技术公众号:JavaPub | 限时免费领取原创PDF

评论

发布
暂无评论
《面试1v1》java注解_Java_JavaPub_InfoQ写作社区