anno2_反射

1.反射获取运行时类的完整结构

获取属性,方法,构造方法

package com.yang;

import javax.xml.transform.Source;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Test10 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
        Class c1 = Class.forName("com.yang.User");
       // Class c1 = new User().getClass(); 等同于上面的
        //1.获取属性值
        Field name = c1.getDeclaredField("name"); //获取指定的属性
        System.out.println(name);
        Field number = c1.getField("number");//获取指定的public修饰的属性,私有的看不到
        System.out.println(number);

        Field[] fields = c1.getFields();        //只能找到public修饰的属性,私有的看不到
        Field[] fields1 = c1.getDeclaredFields(); //获取全部的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        //2.获取方法
        System.out.println("==========获取方法===========");
        Method getAge = c1.getMethod("getAge"); //获取指定的public方法
        System.out.println(getAge);
        Method[] methods = c1.getMethods();   //获取本类及父类的所有的public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("====================");
        //getDeclaredMethod()有参无参用于区分有参构造和无参构造
        Method getAge1 = c1.getDeclaredMethod("getAge",null);//获取指定的方法,getAge()没有参数,不传就是null
        Method setName = c1.getDeclaredMethod("setName", String.class);
        System.out.println(getAge1);
        System.out.println(setName);
        System.out.println("-----------------------");
        Method[] declaredMethods = c1.getDeclaredMethods(); //获取本类的所有的方法,包括私有的
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        Method enclosingMethod = c1.getEnclosingMethod();
        System.out.println(enclosingMethod);
        //3.获取构造方法
        System.out.println("====================");
        Constructor constructor = c1.getConstructor();
        System.out.println(constructor);
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);//获取有参构造器
        System.out.println(declaredConstructor);
        //获取指定构造器
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor1 : constructors) {
            System.out.println(constructor1);
        }
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();
        for (Constructor declaredConstructor1 : declaredConstructors) {
            System.out.println(declaredConstructor1);
        }

    }
}
2.动态创建对象执行方法

​ 创建类的对象:调用Class对象的newInstance()方法

  • 类必须要有一个无参构造器;
  • 类的构造器的访问权限必须足够

如果没有无参构造,要在操作的时候明确调用类的构造器,并将参数传进去,才可以实例化操作

  • 通过class类的getDeclaredConstructor()取得本类指定形参类型的构造器

  • 传递的参数为对象数组

  • 通过constructor实例化对象

    package com.yang;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Test11 {
        public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
            Class c1 = Class.forName("com.yang.User");//获得class对象
            //构造一个对象
      //      User user = (User) c1.newInstance();//本质是调用了类的无参构造器
      //      System.out.println(user); //User{name='null', age=0, id=0}
            //通过构造器创建对象,可以没有无参构造
            Constructor onstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
            User user2 = (User) onstructor.newInstance("zhangsan", 2, 4);
            System.out.println(user2);
            //通过反射调用普通方法
            User user3 = (User) c1.newInstance();
            /*通过反射获取一个方法
            invoke(对象,”方法的值“):激活的意思
             */
            Method setName = c1.getDeclaredMethod("setName", String.class);
            setName.invoke(user3,"张三");
            System.out.println(user3.getName());
    
            //通过反射操作属性
            User user4 = (User) c1.newInstance();
            Field name = c1.getDeclaredField("name");
            //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
            name.setAccessible(true);//方法,字段和构造器都有这个方法
            name.set(user4,"张三2");
            System.out.println(user4.getName());
    
    
    
        }
    }
    
3.性能分析

普通方式调用

反射方式调用

放射方式调用 关闭检测

三种方式对比,处理数据的执行时间

package com.yang;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test12 {
    //普通方式调用
    public static void test01(){
        User user = new User();
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            user.getName();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("普通方式执行10亿次:"+(endTime-startTime)+"ms");
    }
    //反射方式调用
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);

        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("反射方式执行10亿次:"+(endTime-startTime)+"ms");
    }
    //放射方式调用  关闭检测
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName = c1.getDeclaredMethod("getName", null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000000; i++) {
            getName.invoke(user,null);
        }
        long endTime = System.currentTimeMillis();
        System.out.println("关闭检测反射方式执行10亿次:"+(endTime-startTime)+"ms");
    }

    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
        test01();
        test02();
        test03();
    }
}

普通方式执行10亿次:5ms
反射方式执行10亿次:2406ms
关闭检测反射方式执行10亿次:1080ms
4.反射操作泛型
package com.yang;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

//通过反射获取泛型
public class Test13 {
    public void test01(Map<String,User> map , List<User> list){
        System.out.println("test01");
    }
    public Map<String,User>  test02(){
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        Method method01 = Test13.class.getDeclaredMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = method01.getGenericParameterTypes();//获取泛型参数类型
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println(genericParameterType);
            System.out.println("遍历泛型中类型");
            if(genericParameterType instanceof ParameterizedType){//判断是不是参数化类型
                //获得真实的泛型参数信息,强转
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
        System.out.println("-------------------------------");
        Method method02 = Test13.class.getMethod("test02", null);
        Type genericReturnType = method02.getGenericReturnType();
        if(genericReturnType instanceof ParameterizedType){
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }

    }
}
5.获取注解信息
package com.yang;

import java.lang.annotation.*;
import java.lang.reflect.Field;

public class Test14 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class stu = Class.forName("com.yang.Stu");
        Annotation[] annotations = stu.getAnnotations();
        //通过反射获得注解
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获得注解的value值
        System.out.println("-------------");
        TableYang annotation = (TableYang) stu.getAnnotation(TableYang.class);
        System.out.println(annotation.value());
        //获得指定注解
        Field name = stu.getDeclaredField("name");
        FieldYang annotation1 = name.getAnnotation(FieldYang.class);
        System.out.println(annotation1.columnName());
        System.out.println(annotation1.length());
        System.out.println(annotation1.type());

        Field id = stu.getDeclaredField("id");
        FieldYang annotation2 = id.getAnnotation(FieldYang.class);
        System.out.println(annotation2.columnName());
        System.out.println(annotation2.length());
        System.out.println(annotation2.type());

    }

}
@TableYang("db_stu")
class Stu{
    @FieldYang(columnName="db_name",length = 3,type = "varchar")
    private String name;
    @FieldYang(columnName="db_age",length = 10,type = "int")
    private int age;
    @FieldYang(columnName="db_id",length = 10,type = "int")
    private int id;

    public Stu() {
    }

    public Stu(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 "Stu{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", id=" + id +
                '}';
    }
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableYang{
    String value();
}
//属性的注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface FieldYang{
    String columnName();
    String type();
    int length();
}
结果:
    @com.yang.TableYang(value="db_stu")
-------------
db_stu
db_name
3
varchar
db_id
10
int

进程已结束,退出代码0

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值