Java 泛型,反射,注解释义

版权声明:本文为Aile原创,若需转载请标明出处 https://blog.csdn.net/ware00/article/details/82980051

导言:由于Android热门框架Retrofit,Eventbus,BufferKinfe源码不同程度的使用泛型,反射和注解,所以有必要对最基础的知识进行记录,别有时还晕乎乎,一句话总结,泛型解决类型转换,反射动态获取类所有信息并设置,注解告诉编译器如何执行程序

泛型:

定义:
实质是类型参数化,在编译时免去强制类型转换的麻烦,在运行时由具体的类型来替换这个泛型参数,也就是避免类型转换出现异常的东西

实例:

//能检查编译时类型的错误
public void test1() throws Exception {
        List<String> list = new ArrayList<>();
        list.add("aaaa");
//      list.add(1);// 编译时期报错
        String str = list.get(1); 
    }

//泛型正确和错误写法
public void test2() throws Exception {
        // 声明泛型集合,四种正确写法
        List<Object> list1 = new ArrayList<Object>();
        List<String> list2 = new ArrayList<String>();
        List list3 = new ArrayList<String>();
        List<Integer> list4 = new ArrayList();
        
        // 错误,头大脚轻
        //List<Object> list5 = new ArrayList<String>();
        // 错误: 泛型类型必须是引用类型,不能为基本类型
        //List<int> list6 = new ArrayList<int>();
    }

//泛型类
public class Demo1<T> {
    // 定义泛型方法
    public <K> T aile(T t,K k) {
        return null;
    }
    // 测试方法
    public void test() throws Exception {
        //在创建泛型类对象的时候,确定类型
        Demo1<String> demo = new Demo1<String>();
        demo.aile("test", 1);
    }
}

//泛型方法
public class Demo2 {
    // 定义泛型方法
    public <K,T> T aile(T t,K k) {
        return null;
    }
    // 测试方法
    public void test() throws Exception {
        //在使用泛型方法的时候,确定泛型类型
        aile(1.0f, 1);
    }
}

//泛型接口
public interface IDao<T> {
    void aile(T t );
    void ware(T t );
}
//实现泛型接口1
public class Dao<T> implements IDao<T> {}
//实现泛型接口2
public class AnimalDao implements IDao<Animal>{}

//泛型关键字
? : 只接收值 
extends: 元素的类型必须继承指定类
super: 元素的类型必须是指定类的父类

//? 的使用
public class test1 {
    public void aile(List<?> list) {
        // 只能获取、迭代list,不能编辑list,比如打印打印数据,一般在方法参数中用
        for (Object o : list) {
         Log.i("info",o+"");
     }
    }
}

//extends 的使用,必须是Number的子类
public class test2 {
    public void aile(List<? extends Number> list) {
    }
    public void test() throws Exception {
        List<Double> list1 = new ArrayList<Double>();
        List<Float> list2 = new ArrayList<Float>();
        List<Integer> list3 = new ArrayList<Integer>();
        List<String> list4 = new ArrayList<String>();
        //调用
        aile(list1);
        aile(list2);
        aile(list3);
	    //报错
        //aile(list4);
    }
}

//super 的使用,必须是String的父类
public class test3{
    public void aile(List<? super String> list) {
    }
    public void test() throws Exception {
        List<Object> list1 = new ArrayList<Object>();
        List<String> list2 = new ArrayList<String>();
        List<Integer> list3 = new ArrayList<Integer>();
        aile(list1);
        aile(list2);
        //报错
        //aile(list3);
    }
}

反射:

定义:
对于任意一个类,可以动态的获取类、属性、方法的信息,也能构造对象并控制对象的属性和行为

实例:

public class Bean {
    // 属性
    private int id = 1000;
    private String name = "aaaa";
    // 无参构造器
    public Bean(){
        System.out.println("Bean");
    }
    // 带参构造器
    public Bean(String name){
        System.out.println("Bean" + name);
    }
    // 方法
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
// 反射使用
public class test {
    //获取类创建实例
    public void testClass() throws Exception {
        // 类全名
        String className = "cn.aile.Bean";
        // 得到类字节码
        Class<?> clazz = Class.forName(className);
        // 创建无参对象
        //Bean bean = (Bean) clazz.newInstance();
        // 创建含参对象
        Constructor<?> constructor = clazz.getDeclaredConstructor(String.class);
        Bean bean = (Bean) constructor.newInstance("Jack");
    }
    //获取属性名称、值
    public void testField() throws Exception {
        //类全名
        String className = "cn.aile.Bean";
        //得到类字节码
        Class<?> clazz = Class.forName(className);
        // 对象
        Bean bean =  (Bean) clazz.newInstance();
        //获取所有的属性名称
        Field[]  fs =  clazz.getDeclaredFields();
        // 遍历:输出每一个属性名称、值
        for (Field f : fs) {
            //设置强制访问
            f.setAccessible(true);
            //名称
            String name = f.getName();
            //获取值
            Object value = f.get(bean);
	    //设置值
	    f.set(bean,"bbbb");
        }
    }
    //获取方法
    public void testMethod() throws Exception {
        //类全名
        String className = "cn.aile.Bean";
        //得到类字节码
        Class<?> clazz = Class.forName(className);
        //对象
        Bean bean =  (Bean) clazz.newInstance();
        //获取方法对象
        Method m = clazz.getDeclaredMethod("getId");
        //调用方法
        Object r_value = m.invoke(bean);
    }
}

注解:

定义:
注解:告诉编译器如何运行程序,有java内置(@Override,@Deprecated,@SuppressWarnings)和自定义的注解
注释, 给程序员阅读的描述信息
元注解:修饰注解的注解

实例:
1:java内置注解

   //重写父类的方法
    @Override
    public String toString() {
        return super.toString();
    }
    //抑制编译器警告
    @SuppressWarnings({"unused","unchecked"})
    private void aile1() {
        List list = null;
    }
    //标记方法过时
    @Deprecated
    private void aile2() {
    }

2:自定义注解,可以给类、字段、方法上添加描述信息

   //注解格式
    public @interface Info {
    String name();
    int age();
    }
    //使用
    @Info(name = "aaa", age = 18)
    public void aile() {
    }

3:元注解
@Target:指定注解的可用范围
TYPE, 类
FIELD, 字段
METHOD, 方法
PARAMETER, 参数
CONSTRUCTOR, 构造器
LOCAL_VARIABLE 局部变量

@Retention:指定注解的声明周期
RetentionPolicy.SOURCE 在源码时有效
RetentionPolicy.CLASS 在字节码时有效
RetentionPolicy.RUNTIME 在运行时有效

@Target({TYPE}) //指定该注解在类上使用
@Retention(RetentionPolicy.RUNTIME)  //在运行时有效
public @interface Aile {
    String info();
}

好了,算是复习了一遍基础知识,结束.

猜你喜欢

转载自blog.csdn.net/ware00/article/details/82980051