反射的介绍与使用

Java 反射(Reflection)是可以让我们在运行时获取类的方法、属性、父类、接口等类的内部信息的机制。

 什么是反射?

个人理解:反着来

官方理解:反射是一个机制,利用反射机制动态的实例化对象、读写属性、调用方法、构造函数

反射能干什么、有什么用?

Java Reflection功能非常强大,并且非常有用

比如:

1.获取任意类的名称、package信息、所有属性、方法、注解、类型、类加载器等

2.获取任意对象的属性,并且能改变对象的属性。

3.调用任意对象的方法

4.判断任意一个对象所属的类

5.实例化任意一个类的对象

6.通过反射我们可以实现动态装配,降低代码的耦合度,动态代理等。

如何使用反射

一切与反射相关的代码都从获取类对应的字节码对象开始

三种:

1.对象名.getClass()

 Student stu=new Student();
 Class stuClass = stu.getClass();

先实例化一个Student对象,再用对象名点

2.类名.class

 Class<Student> stuClass = Student.class;

就是直接用类名点

3.Class.forName("类的全路径")

Class stuClass = Class.forName("com.zking.entity.Student");

 然后三种都用下面这些

System.out.println("类名全路径"+stuClass.getName());
System.out.println("类名"+stuClass.getSimpleName());
System.out.println("包名"+stuClass.getPackage());

                                       

都将会出现这些东西

传统实例化与反射实例化的区别

1.传统实例化对象

Student  stu  =  new  Student();

传统的只能实例化公共的,不能实例化私有的、受保护的等等

2.反射实例化对象

Class stuClass = Class.forName("com.zking.entity.Student");
Object newInstance = stuClass.newInstance();

反射是可以使用所有的包括私有的、受保护的等等

Class.forName指定全路径名必须正确,否则将报ClassNotFoundException错误;

反射应用

类名用途 
Class类 代表类的实体,在运行的Java应用程序中表示类和接口 
Field类 代表类的成员变量(成员变量也成为类的属性)
Method类代表类的方法
Constructor类代表类的构造函数

1.读取属性(Field)

类名用途
getField(String name)获取某个公共的属性对象 
getFields()获取所有公共的属性对象
getDeclaredField(String name)获取某个属性对象(public和非public)
getDeclaredFields()获取所有属性对象(public和非public)
setAccessible(boolean flag)默认值false,设置true使私有成员允许访问
set(Object,Object) 属性赋值
get(Object) 获取属性 

1.1获取单个公共的属性

Field field = stuClass.getField("age");

1.2获取单个所有的属性

 Field field = stuClass.getDeclaredField("sname");

前两个可以使用下面的方法来测试

 System.out.println("获取属性名"+field.getName());
System.out.println("获取属性类型"+field.getType());
 System.out.println("访问修饰符"+field.getModifiers());        

1.3获取所有公共的属性

 Field[] fields = stuClass.getFields();

1.4获取所有属性

 Field[] fields = stuClass.getDeclaredFields();

后面两个需要用到迭代器循环

 for (Field field : fields) {
     System.out.println("获取属性名"+field.getName());
     System.out.println("获取属性类型"+field.getType());
     System.out.println("访问修饰符"+field.getModifiers());
     System.out.println("-------------");
 }

出来的效果都是差不多的

1.5属性赋值和获取属性值

先获取属性

 //获取单个所有属性
        Field field = stuClass.getDeclaredField("sname");

//        属性赋值
//        设置权限(在对类中私有属性赋值是必须设置访问权限)
        field.setAccessible(true);
//        参数1:代表实例化对象  2:赋的值
        field.set(newInstance,"张张");

//        获取属性
        Object o = field.get(newInstance);
        System.out.println(o);

2.调用方法(Method)

类名 用途 
getMethod(String name, Class<>… parameterTypes)获取该类某个公共的方法
getMethods()  获取该类所有公共的方法 
getDeclaredMethods(String name,Class<>… parameterTypes)获取该类某个方法(public和非public)
getDeclaredMethod() 获取该类所有方法(public和非public)
setAccessible(boolean flag)  默认值false,设置true使私有方法允许访问
invoke(Object obj, Object… args) 执行方法

那我们先回顾一下方法的类型:

        有参有返回,无参无返回,有参无返回,无参有返回

2.1获取单个公共的属性

Method method = stuClass.getMethod("hello");

2.2获取单个所有的属性

 Method method = stuClass.getDeclaredMethod("add",Integer.class,Integer.class);

前两个可以使用下面的方法来测试

 System.out.println("方法名"+method.getName());
 System.out.println("返回类型"+method.getReturnType());
 System.out.println("访问修饰符"+method.getModifiers());
 System.out.println("方法参数数量"+method.getParameterCount());          

2.3获取所有公共的属性

  Method[] methods = stuClass.getMethods();

2.4获取所有属性

Method[] methods = stuClass.getDeclaredMethods();

后面两个需要用到迭代器循环

for (Method method :methods) {
    System.out.println("方法名"+method.getName());
    System.out.println("返回类型"+method.getReturnType());
    System.out.println("访问修饰符"+method.getModifiers());
    System.out.println("方法参数数量"+method.getParameterCount());             
    System.out.println("------------");
 }

2.5调用方法

//        获取单个所有属性
        Method method = stuClass.getDeclaredMethod("add",Integer.class,Integer.class);

        //设置权限
        method.setAccessible(true);
//        调用方法
//        参数1:实例化对象名  2:方法本身所需参数(可变参数)
        Object invoke = method.invoke(newInstance, 5, 20);
        System.out.println(invoke);

3.构造函数(Constructor)

类名用途 
getConstructor(Class<>… parameterTypes) 获取该类中与参数类型匹配的公有构造方法
getConstructors()获取该类的所有公共构造方法
getDeclaredConstructors(Class<>… parameterTypes)获取该类中与参数类型匹配的构造方法
getDeclaredConstructors() 获取该类所有构造方法(public和非public)


 

3.1获取该类中与参数类型匹配的公有构造方法

Constructor constructor = stuClass.getConstructor(String.class);
System.out.println(constructor);

3.2获取该类的所有公共构造方法

Constructor[] constructors = stuClass.getConstructors();
for (Constructor constructor : constructors) {
    System.out.println(constructor);
}

3.3获取该类中与参数类型匹配的构造方法

Constructor constructor = stuClass.getDeclaredConstructor(Integer.class);
System.out.println(constructor);

 3.4获取该类所有构造方法(public和非public)

Constructor[] constructors = stuClass.getDeclaredConstructors();
for (Constructor constructor : constructors) {
      System.out.println(constructor);
 }

3.5通过构造函数实例化对象

       
        //getConstructor(Class<>… parameterTypes) 获取该类中与参数类型匹配的公有构造方法
         Constructor constructor = stuClass.getConstructor(String.class);
        //System.out.println(constructor);
        //设置权限
        constructor.setAccessible(true);
        //通过构造函数实例化对象
        Object o = constructor.newInstance("hh");
        System.out.println(o);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值