javaSE5内置的3種注解
@Override,表示目前的方法定義将覆寫超類中的方法。
@Deprecated,使用了注解為它的元素編譯器将發出警告,因為注@Deprecated是不贊成使用的代碼,被棄用的代碼。
@SuppressWarnings,關閉不當編譯器警告資訊。
四種元注解
元注解就是用在注解上的注解,定義注解的作用域和聲明周期。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcugDM1UjNwIjNxETN1EzLcdmbhlma1h2cvFWa49CXyVGdzFWbvw1dhJ3LcdWbp9CXul2dyVEdzVmQvwVbvNmLlVGdpd2Lc9CX6MHc0RHaiojIsJye.png)
定義一個注解的方式:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
}
除了@符号,注解很像是一個接口。定義注解的時候需要用到元注解,上面用到了@Target和@RetentionPolicy,它們的含義在上面的表格中已近給出。
在注解中一般會有一些元素以表示某些值。注解的元素看起來就像接口的方法,唯一的差別在于可以為其制定預設值。沒有元素的注解稱為标記注解,上面的@Test就是一個标記注解。
注解的可用的類型包括以下幾種:所有基本類型、String、Class、enum、Annotation、以上類型的數組形式。元素不能有不确定的值,即要麼有預設值,要麼在使用注解的時候提供元素的值。而且元素不能使用null作為預設值。注解在隻有一個元素且該元素的名稱是value的情況下,在使用注解的時候可以省略“value=”,直接寫需要的值即可。
下面看一個定義了元素的注解。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public String id();
public String description() default "no description";
}
定義了注解,必然要去使用注解。
public class PasswordUtils {
@UseCase(id = 47, description = "Passwords must contain at least one numeric")
public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UseCase(id = 48)
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
}
}
使用注解最主要的部分在于對注解的處理,那麼就會涉及到注解處理器。
從原理上講,注解處理器就是通過反射機制擷取被檢查方法上的注解資訊,然後根據注解元素的值進行特定的處理。
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
public static void trackUseCases(List<Integer> useCases, Class<?> cl) {
for (Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if (uc != null) {
System.out.println("Found Use Case:" + uc.id() + " "
+ uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for (int i : useCases) {
System.out.println("Warning: Missing use case-" + i);
}
}
一句話總結:注解是java的一種類型,通過注解我們可以更加簡化代碼。自定義注解,然後利用反射機制通過注解器獲注解資訊,然後根據注解的值進行特殊處理。
一個案例:
注解連結JDBC
注解類:
package Main.jdbcAnnotion;
import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.FIELD,ElementType.PARAMETER,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface JDBCConfig {
String ip();
int port() default 3306;
String database();
String encoding();
String loginName();
String password();
}
測試類:
package Main.jdbcAnnotion;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
@JDBCConfig(ip="127.0.0.1",database = "mysql",encoding = "UTF-8",loginName = "root",password = "123")
public class TestAnnotation {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/** * 通過反射
*
* * @return * @throws SQLException
* * @throws NoSuchFieldException
* * @throws SecurityException
* */
public static Connection getConnection()throws SQLException,NoSuchFieldException,SecurityException{
JDBCConfig config = TestAnnotation.class.getAnnotation(JDBCConfig.class);
String ip = config.ip();
int port = config.port();
String database = config.database();
String encoding = config.encoding();
String loginName = config.loginName();
String password = config.password();
String url = String.format("jdbc:mysql://%s:%d/%s?characterEncoding=%s", ip, port, database, encoding);
return DriverManager.getConnection(url,loginName,password);
}
public static void main(String[] args)throws NoSuchFieldException,SecurityException,SQLException, NoSuchMethodException {
Connection connection=getConnection();
System.out.println(connection);
}
}
案例工程連結:https://gitee.com/BestErwin/java_base_demo/tree/master/Java 語言基礎/語言基礎文法/注解/TestAnnotaion