java基础之反射和泛型以及注解

时间:2022-08-28 14:43:53

 java基础之反射泛型以及注解

泛型擦除

泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息。

声明泛型集合,集合两端类型必须一致。类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型。

实现公用的类和方法,对公用的业务进行抽取。

泛型方法/泛型类/泛型接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class GenericTest
{
  /**
   * 泛型声明,定义泛型方法
   * @param <T>
   * @param <K>
   * @param t
   * @param k
   */
  public <T, K> K save(T t, K k)
  {
    return null;
  }
  @Test
  public void testMethod() throws Exception
  {
    //使用泛型方法: 在使用泛型方法的时候,确定泛型的类型
    save("hello", 1);
  }
}
泛型类:
public class GenericTest<T>
@Test
  public void testMethod() throws Exception
  {
    //使用泛型方法: 在使用泛型方法的时候,确定泛型的类型
    //save("hello", 1);
    //泛型类如何使用:在创建泛型类的时候确定
    GenericTest<String> demo = new GenericTest<String>();
    demo.save("hello", 1); 
}

泛型中的extends 和super的意义:

Extends:定义List<? Extends String>;传入的参数?必须是String类型的子类,否则会报错;
Super:定义List<? Super String>;传入的参数必须是String类型的父类,否则会报错;

Type : 接口,任何类型默认的接口!

反射

反射可以在运行时期动态创建对象,获取对象的属性,方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/** 
 * @ClassName: App 
 * @Description: 反射技术 
 * @author lqw 
 * @date 2016-5-13 下午01:33:55 
 
 */
public class App
{
  @Test
  public void testInfo() throws Exception
  {
    //类全名
    String sql = "com.hbmy.reflect.demo2.Admin";
    //得到类的字节码
    Class<?> clazz = Class.forName(sql);
    /**
     * 创建对象1: 通过默认构造函数创建(简写)
     */
    Admin admin = (Admin) clazz.newInstance();
    /**
     * 创建对象2: 通过无参构造器创建对象
     */
    Constructor<?> constructors = clazz.getDeclaredConstructor();
    constructors.newInstance();
    /**
     * 创建对象3:通过有参构造器创建对象
     */
    Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
    Admin admin2 = (Admin) constructor.newInstance("zhangsan");
    //   System.out.println(admin);
  }
   
  /**
   * 获取属性名称、值
   * getDeclaredFields: 获取所有的包含私有的属性名称
   * getFields:只能访问public的属性
   */
  @Test
  public void testNameAndValue() throws Exception
  {
    //类全名
    String sql = "com.hbmy.reflect.demo2.Admin";
    //得到类的字节码
    Class<?> clazz = Class.forName(sql);
     
    Admin admin = (Admin) clazz.newInstance();
//   Method[] methods = clazz.getMethods();
//   for (Method method : methods)
//   {
//     //设置强制访问
//     method.setAccessible(true);
//     //名称
//     String name = method.getName();
//     System.out.println(name);
//     
//   }
//   Field[] fields = clazz.getFields();//打印出来的结果只有money
    Field[] fields = clazz.getDeclaredFields();
    for (Field field : fields)
    {
      //设置强制访问
      field.setAccessible(true);
      //名称
      String name = field.getName();
      Object value = field.get(admin);
      System.out.println(name + value);
    }
  }
 
  /**
   * 反射获取方法
   */
  @Test
  public void testGetMethods() throws Exception
  {
    //类全名
    String sql = "com.hbmy.reflect.demo2.Admin";
    //得到类的字节码
    Class<?> clazz = Class.forName(sql);
 
    Admin admin = (Admin) clazz.newInstance();
    /*
     * 获取方法对象
     */
    Method declaredMethod = clazz.getDeclaredMethod("getId");
    /**
     * 调用方法
     */
    Object return_value = declaredMethod.invoke(admin);
    System.out.println(return_value);
    Method[] methods = clazz.getDeclaredMethods();
     
    for (Method method : methods)
    {
      method.setAccessible(true);
      String name = method.getName();
      System.out.println(name);
    }
  }

注解

注解的作用

1、 告诉编译器如何去运行

2、 简化(取代)配置文件

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class App
{
  @Override
  public String toString()
  {
    return super.toString();
  }
  @SuppressWarnings({"unused","unchecked"})
  public void save()
  {
    List list = null;
  }
   
  @Deprecated
  public void save1()
  {
 
  }
}

自定义注解: 通过自定义注解可以给类,字段,方法加上描述信息。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public @interface Author
{
  /**
   * 注解属性
   * 1.修饰符为默认或者public
   * 2.不能有主体
   * 3. 如果注解名称为value,使用的时候可以省略名称,直接给值
   */
  String name() default "lqw";
  //带默认值得注解
  int age() default 23;
  String remark();
}

元注解

元注解就是注解的注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
指定注解的可用范围
@Target({
TYPE,
FIELD, 
METHOD, 
PARAMETER, 
CONSTRUCTOR, 
LOCAL_VARIABLE})
注解的生命周期
/**
 * 元注解2: 指定注解的生命周期
 * RetentionPolicy.SOURCE 只在源码级别有效
 * RetentionPolicy.CLASS 只在类的字节码级别有效 默认值
 * RetentionPolicy.RUNTIME 只在运行时期有效
 */
@Retention(RetentionPolicy.SOURCE)

 最后总结一句:注解和反射其实不难,只要不畏惧,注解其实看看源码也就那么回事。至于反射嘛。可以这么说,无反射,则无框架,几乎所有的框架都是通过反射实现的。说白了,反射也就是通过加载类的字节码去获取类里面的方法和属性,其实框架也是这么实现的。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

原文链接:http://blog.csdn.net/lqw_student/article/details/51415307