Java注解和反射
Java注解和反射
注解的作用
- 注解可以被编译器识别
- 可以添加在package,class,method,field上面,添加了额外的辅助信息,可以通过反射机制实现对元数据的访问
package com.wang.annotation;
import java.util.ArrayList;
import java.util.List;
public class learn01 extends Object{
@Override
public String toString() {
return super.toString();
}
@Deprecated
public static void testPrint(){
System.out.println("Deprecated");
}
@SuppressWarnings("all")
public static void testPrint2(){
List list = new ArrayList();
}
public static void main(String[] args) {
testPrint();
}
}
元注解
- @Target:注解的使用范围
- @Retention:在什么级别保存该注解信息,描述注解的生命周期
- @Documented:说明该注解将被包含在的Javadoc中
- @Inherited:说明子类可以继承父类中的该注解
package com.wang.annotation;
import java.lang.annotation.*;
@MyAnnotation
public class learn01 {
@MyAnnotation
public void test(){
}
}
//自定义注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation{}
自定义注解
package com.wang.annotation;
import java.lang.annotation.*;
public class learn03 {
@MyAnnotation2(name = "hahaha", schools = {"kukuku"})
public void test(){
}
@MyAnnotation3("HIHIHI")
public void test2(){
}
}
//自定义注解
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation2{
//注解的参数:参数类型+参数名();有默认值则不需显示赋值,否则必须显示赋值
String name() default "";
int age() default 0;
int id() default -1;
String[] schools() default {"kkkk"};
}
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation3{
//注解的参数:参数类型+参数名();有默认值则不需显示赋值,否则必须显示赋值
String value() default "";
}
反射机制
概述
-
动态语言:运行时可以改变其结构的语言:例如新的函数、对象,甚至代码可以被引进(Object-C,C#,JavaScript)
-
静态语言:运行时结构不可改变(Java,C,C++)
-
Java不是动态语言,但是有一定动态性.
-
优点:利用反射机制,编程更加灵活
-
缺点:影响性能,使用反射基本上是解释操作
-
通过堆内存的方法区中的Class对象(一个类只有一个),获取类的结构,属性和方法
-
相关的API
- java.lang.Class 代表一个类
- java.lang.reflect.*
理解Class类并获取Class实例
package com.wang.reflection;
import java.util.Objects;
public class learn0 extends Object{
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的Class对象
Class name1 = Class.forName("com.wang.reflection.User");
System.out.println(name1);
Class name2 = Class.forName("com.wang.reflection.User");
Class name3 = Class.forName("com.wang.reflection.User");
Class name4 = Class.forName("com.wang.reflection.User");
System.out.println(name2.hashCode());//hashCode相同,一个类在内存只有一个Class对象
System.out.println(name3.hashCode());//类被加载后,整个结构都会被封装在Class对象中
System.out.println(name4.hashCode());
}
}
//实体类
class User{
private String name;
private int age;
private int id;
public User() {
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
// @Override
// public boolean equals(Object o) {
// if (this == o) return true;
// if (o == null || getClass() != o.getClass()) return false;
// User user = (User) o;
// return age == user.age && id == user.id && Objects.equals(name, user.name);
// }
//
// @Override
// public int hashCode() {
// return Objects.hash(name, age, id);
// }
}
package com.wang.reflection;
import java.lang.annotation.Target;
public class learn1 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println(person.name);
//三种方法获取Class对象
Class c1 = person.getClass();
System.out.println(c1.hashCode());
Class c2 = Class.forName("com.wang.reflection.Student");
System.out.println(c2.hashCode());
Class c3 = Student.class;
System.out.println(c3.hashCode());
Class c4 = Integer.TYPE;//基本包装类型有一个TYPE属性
System.out.println(c4);
//获取父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person{
public Student() {
this.name = "student";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "teacher";
}
}
反射的性能
package com.wang.reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class learn02 {
public static void main(String[] args) throws Exception {
t1();
t2();
t3();
}
private static void t3() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Student student = new Student();
Class s = student.getClass();
Method method = s.getDeclaredMethod("getId",null);
method.setAccessible(true);
long startTime = System.currentTimeMillis();
for(int i = 0 ; i < 2100000000; ++i){
method.invoke(student,null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭检测反射方法"+(endTime-startTime)+"ms");
}
private static void t2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Student student = new Student();
Class s = student.getClass();
Method method = s.getDeclaredMethod("getId",null);
long startTime = System.currentTimeMillis();
for(int i = 0 ; i < 2100000000; ++i){
method.invoke(student,null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方法"+(endTime-startTime)+"ms");
}
private static void t1() {
Student student = new Student();
long startTime = System.currentTimeMillis();
for(int i = 0 ; i < 2100000000; ++i){
student.getId();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法"+(endTime-startTime)+"ms");
}
}

浙公网安备 33010602011771号