Java笔记--注解

Java注解(Annotation)

1,什么是注解?

注解就是代码中特殊的标记,这些标记在编译,类加载和运行时可以被读取,并且执行相应的处理。注解不会影响程序代码的执行

2,基本的注解

@Override
@Deprecated
@SuppressWarnings
@SafeVarargs(Java7新增)
@FunctionalInterface(Java8新增)

2.1,@Override

public class Demo01{
    public void info(){
        System.out.println("233333");
    }
}

class A extends Demo01{

    @Override
    public void info() {
        System.out.println("2444444");
    }

}

@Override用来指定方法覆盖,它可以强制一个子类必须覆盖父类方法,这也是最常见的一个注解了,它告诉编译器检查这个方法,保证父类包含一个方法重写,否则报错

2.2,@Deprecated

该注解表示某个程序元素(类,方法等)已过时,当其他程序使用已过时的类,方法时,编译器会给出警告。

2.3,@SuppressWarnings

该注解可以抑制编译器的警告

3,JDK元注解

元注解用于修饰其他的注解定义

3.1,@Retention
@Retention包含一个RetentionPolicy类型的value变量,

1,RetentionPolicy.Class:编译器把注解记录在class文件中,运行java程序时,JVM不可获取注解信息,这是默认值

2,RetentionPolicy.RUNTIME:编译器把注解记录在class文件中,运行java程序时,JVM可获取注解信息,程序可以通过反射获取该注解信息

3,RetentionPolicy.SOURCE:注解只保留在源代码中,编译器直接丢弃这种注解

//定义下面的@Testable注解保留到运行时
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Testable{}

3.2,@Target

它用于指定被修饰的注解能用于修饰那些程序单元,包含一个ElementType类型value变量
1,ElementType.FIELD:指定该注解只能修饰构造器
2,ElementType.METHOD:指定该注解只能修饰方法定义
3,ElementType.PACKAGE:指定该注解只能修饰包定义
4,ElementType.PARAMETER:指定该注解可以修饰参数

//@ActionListenerFor注解只能修饰成员变量
@Target(ElementType.FIELD)
public @interface ActionListenerFor{}

3.3,@Documented

被该元注解修饰的注解类将被javadoc工具提取成文档

//定义Test注解将被javadoc工具提取
//自定义注解使用@interface关键字
@Documented
public @interface Test{}

3.4,@Inherited

允许子类继承父类中的注解

//@Inheritable具有继承性了
@Inherited
public @interface Inheritable {
}
@Inheritable
class Base{

}

public class Demo02 extends Base{
    public static void main(String[] args) {
        System.out.println(Demo02.class
                .isAnnotationPresent(Inheritable.class));
    }
}

Base类使用@Inheritable修饰,Demo02类继承Base类,也被@Inheritable修饰,打印结果为true

4,注释的具体的使用

使用注释修饰了类,方法,成员变量等成员后,这些注解不会自己生效,必须要由开发者提供相应的工具来提取并处理注解信息,从Java5开始,java.lang.reflect包提供的反射API增加了读取运行时注解的能力

通过注解来简化事件编程

1,定义了一个@ActionListenerFor注解,指定了一个listener成员变量,用于指定监听器的实现类

import java.awt.event.ActionListener;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionListenerFor {
    //定义一个成员变量用于保存监听器实现类
    Class<? extends ActionListener> listener();
}

2,使用@ActionListenerFor注解为两个按钮绑定时间监听器,使用注解@ActionListenerInstaller时传入listener元数据,该数据用于设定每个按钮的监听器实现类

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

class OkListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, "单击了确认按钮");

    }
}

class CancelListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        JOptionPane.showMessageDialog(null, "单击了取消按钮");
    }
}

public class AnnotationTest {
    private JFrame mainwin = new JFrame("1");
    @ActionListenerFor(listener = OkListener.class)
    private JButton ok = new JButton("确定");
    @ActionListenerFor(listener = CancelListener.class)
    private JButton cancel = new JButton("取消");

    public void init() {
        JPanel jp = new JPanel();
        jp.add(ok);
        jp.add(cancel);
        mainwin.add(jp);
        //处理本程序中的注解
        ActionListenerInstaller.processAnnotations(this);
        mainwin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainwin.pack();
        mainwin.setVisible(true);
    }
    public static void main(String[] args) {
        new AnnotationTest().init();
    }
}

3,使用ActionListenerInstaller类来处理程序中的注解,该处理器分析取自目标对象中的所有成员变量,如果没有这个处理器,注解并不能起作用

import java.awt.event.ActionListener;
import java.lang.reflect.Field;

import javax.swing.AbstractButton;

public class ActionListenerInstaller {
    public static void processAnnotations(Object obj) {
        try {
            Class c1 = obj.getClass();
            for(Field f:c1.getDeclaredFields()) {
                //将该成员变量设置成可自由访问
                f.setAccessible(true);
                //获取该成员变量上ActionListenerFor类型的注解
                ActionListenerFor a = f.getAnnotation(ActionListenerFor.class);
                Object fObj = f.get(obj);
                if(a!=null && fObj!=null && fObj instanceof AbstractButton) {
                    //获取a注解里的listener元数据(它是一个监听器类)
                    Class<? extends ActionListener> listenerClazz = a.listener();
                    //使用反射创建listener类对象
                    ActionListener a1 = listenerClazz.newInstance();
                    AbstractButton ab = (AbstractButton) fObj;

                    ab.addActionListener(a1);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

程序运行结果:
这里写图片描述
这里写图片描述
这里写图片描述
这是一个很典型的注解应用的例子,在安卓中也是能经常能看到,其他的框架中也是很常见的,掌握这种注释绑定事件编程十分有必要

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你的问题是关于Gson下划线转驼峰注解的使用吗?下划线和驼峰式命名是两种常见的命名规则,在Java开发中也经常会使用到。Gson是Google开发的一个Java库,用于将Java对象转换为JSON格式的数据。在使用Gson进行JSON解析时,如果JSON中的属性名采用了下划线命名,则可以使用Gson提供的@SerializedName注解进行转换。 使用@SerializedName注解需要指定一个value值,用于表示JSON中的属性名,同时还可以指定一个alternate值,用于表示其他可能的属性名。例如,如果JSON中的属性名为"user_name",则可以使用@SerializedName("user_name")注解将其转换为Java对象中的"userName"属性。 另外,如果Java对象中的属性名采用了驼峰式命名,则可以使用Gson提供的FieldNamingStrategy接口进行转换。通过实现FieldNamingStrategy接口中的方法,可以自定义属性名的转换规则。例如,可以实现一个驼峰式转下划线的命名策略: ``` public class CamelCaseToUnderscoresNamingStrategy implements FieldNamingStrategy { @Override public String translateName(Field field) { String name = field.getName(); StringBuilder result = new StringBuilder(); for (int i = 0; i < name.length(); i++) { char ch = name.charAt(i); if (Character.isUpperCase(ch)) { result.append("_").append(Character.toLowerCase(ch)); } else { result.append(ch); } } return result.toString(); } } ``` 使用时可以通过GsonBuilder设置: ``` Gson gson = new GsonBuilder() .setFieldNamingStrategy(new CamelCaseToUnderscoresNamingStrategy()) .create(); ``` 这样,在解析JSON时就可以将驼峰式命名的属性名转换为下划线命名了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值