Java 反射-基础

文章介绍了Java中的反射机制,它是Java被视为动态语言的关键。反射允许程序在运行时获取类的内部信息并操作对象。主要API包括Class,Method,Field和Constructor。反射提供了动态创建对象、操作泛型和注解的能力,但也存在性能影响。文章通过示例展示了如何通过反射获取类的结构、创建对象以及操作注解。
摘要由CSDN通过智能技术生成

反射(Reflection):

        动态语言:

                在运行时可以改变其结构的语言。例如:Object-C,C#,JavaScript,PHP,Python。

        反射是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API获得类的任何内部信息并能直接操作任意对象的内部属性及方法。

//主要API
java.lang.Class//代表一个类
java.lang.reflect.Method//代表类的方法
java.lang.reflect.Field//代表类的成员变量
java.lang.reflect.Constructor//代表类的构造器

//Object类中定义了如下方法,此方法被所有的子类继承
public final Class getClass();
//返回值是一个Class类,此类是Java反射的源头,实际上所谓反射从程序的运行结果来看:通过对象反射求出类的名称。

正常方法与反射方法的对比:

        正常方法:1:引入需要的"包类"名称。2:通过new实例化。3:取得实例化对象

        反射方法:1:找到实例化对象。2:使用getClass()方法。3:得到完整的"包类"名称

        优点:可以实现动态创建对象和编译,体现出很大的灵活性。

        缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么,并且它能满足我们的要求。这类操作总是慢于直接执行相同的操作。

 

        那些有Class对象:class,interface,[],enum,annotation,primitive type(基本数据类型),void

Class c1=Object.class;//类
Class c2=Comparable.class;//接口
Class c3=String[].class;//一维数组
Class c4=int[][].class;//二维数组
Class c5=Override.class;//Override注解
Class c6=ElementType.class;//枚举
Class c7=Integer.class;//基本数据类型
Class c8=void.class;//void
Class c9=Class.class;//Class

//只要元素类型与维度一样,就是同一个Class,例如下面的 a和b
int[] a=new int[10];
int[] b=new int[100];

        获得类的运行时结构:

Class c1=Object.class;//类
c1.getMethods();//获得全部方法
c1.getDeclaredMethod();//获得指定方法
//其他的类似(属性,构造器)

 

反射可以做什么?

        创建类的对象:

                调用Class对象的newInstance()方法:

                        ①:类必须有一个无参数的构造器。

                        ②:类的构造器的访问权限需要足够。

        反射操作泛型:

        ParameterrizedType:表示一种参数化类型,比如Collection<String>。

        GenericArrayType:表示一种元素类型是参数化类型或者类型变量的数组类型。

        TypeVariable:是各种类型变量的公共父接口。

        WildcardType:代表一种通配符类型表达式。

        反射操作注解:

//c1是一个反射对象
c1.getAnnotations();//获得类所有的注解
c1.getAnnotation();//获得类指定的注解

 

反射相关操作练习:

public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1=Class.forName("s202303.Thread.User");//路径
        //输出c1
        System.out.println(c1);

        Method[] methods=c1.getMethods();
        //输出c1中的方法
        for(Method method:methods){
            System.out.println(method);
        }

        //一个类在内存中只有一个Class对象
        //一个类被加载后,类的整个结构都会被封装在Class对象中
        Class c2=Class.forName("s202303.Thread.User");
        Class c3=Class.forName("s202303.Thread.User");
        Class c4=Class.forName("s202303.Thread.User");
        System.out.println(c2.hashCode());
        System.out.println(c3.hashCode());
        System.out.println(c4.hashCode());
        //三个输出是一样的

        //获得反射的途径
        User user=new User();
        //通过对象获得
        Class c5=user.getClass();
        //通过forName获得
        Class c6=Class.forName("s202303.Thread.User");
        //通过类名.class获得
        Class c7=User.class;
        //基本内置类型的包装类都有一个Type属性
        Class c8=Integer.TYPE;

        //通过反射获得对象的注解
        Annotation[] annotations=c1.getAnnotations();
        for (Annotation annotation :annotations) {
            System.out.println(annotation);
        }

        //获得注解的value的值
        TableSong table=(TableSong) c1.getAnnotation(TableSong.class);
        System.out.println(table.value());

        //获得类指定的注解
        Field f=c1.getDeclaredField("name");
        FieldSong annotation=f.getAnnotation(FieldSong.class);
        System.out.println(annotation.age());
        System.out.println(annotation.Name());
        System.out.println(annotation.id());
    }
}
//实体类
@TableSong("user")
public class User{
    @FieldSong(Name = "userName" ,id=1,age=10)
    private String name;
    private int id;
    private  int age;

    public User(){

    }
    public User(String name,int id,int age){
        this.name=name;
        this.age=age;
        this.id=id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", age=" + age +
                '}';
    }
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableSong{
    String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldSong{
    String Name();
    int id();
    int age();
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值