java基础--反射学习笔记

本文深入解析Java反射机制,涵盖基本概念、动态获取类信息、创建对象、调用方法及成员变量,展示反射在运行时的强大功能。

 

一:基本概念

什么是反射

反射是java程序开发语言的特征之一,它允许java程序获取自身的信息,并且可以操作类或对象的内部属性。综合来说:对于一个类,我们知道它的属性和方法,对于一个对象,我们能够调用它的的属性和方法,这种动态获取信息以及动态调用方法的功能称为java的反射机制。

为什么需要反射,反射的作用

在java编译存在两种编译:静态编译,动态编译。静态编译:在编译时确定类型,动态编译在运行时确定类型,动态编译最大限度地发挥了Java的灵活性,体现了多态的应用,可以减低类之间的耦合性。 Java反射是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时取得任何一个已知名称的class的内部信息。反射允许在运行时检查,修改程序的结构和行为,,java相关类型信息都在编译保存在class文件中,如果想在运行时该便,需要用到反射。简而言之:通过反射,我们可以获得程序或程序集中的每一个类型的成员和成员信息。腱反射的核心就是jvm在运行时动态加载类的或调用类的属性方法。

反射的基础:Class类

java程序在运行时保存所有的对象类型信息,而保存这些信息的就是class类。class类型封装了一个对象或者接口运行时的状态,当该类加载时,class类型的对象自动创建。

总的说:

             class类也是类的一种,一个描述类的类,封装了描述的方法,属性等。

             每一个类,java都为其保留了一个不变唯一的class对象,class类对象内容就是你创建对象的类的类型信息。比如创建一              个A类,java生成一个A类的class类对象。A类的对象都要通过class类对象实例化。

             class类的对象只能由jvm创建。因为它没有公共构造函数。

 

二、反射的基本运用

如何使用反射?

首先获取到Class对象,其方式有三种

            //(1)使用Class类的forName静态方法:
            Class<?> class1 = Class.forName("java.lang.String");

            //(2)直接获取某一个对象的class
            Class<?> class2=String.class;

            //(3)调用某个对象的getClass()方法
            Class<? extends String> class3 = new String().getClass();
            
            //Class对象唯一
            System.out.println(class1.equals(class2));   //true
            System.out.println(class3.equals(class2));   //true

 

1创建对象

通过反射创建对象的方式有两种

(1)直接利用newInstance创建,该方法必须调用的类必须有无参的构造器。

Object o = class1.newInstance();
String o1 = (String) class1.newInstance();

(2)先通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用         指定的构造器构造类的实例。

 //获取String所对应的Class对象
 Class<?> c = String.class;
 //获取String类带一个String参数的构造器
 Constructor constructor = c.getConstructor(String.class);
 //根据构造器创建实例
 Object obj = constructor.newInstance("23333");

2获取方法

三种主要方法

(1) 返回接口或类声明的所有方法,包含私有,公共,但不包含继承

public Method[] getDeclaredMethods() throws SecurityException

  (2)返回某个类的所有公用(public)方法,包括其继承类的公用方法。

public Method[] getMethods() throws SecurityException

   (3)返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应Class的对象    

public Method getMethod(String name, Class<?>... parameterTypes)

方法的调用

public class Son {

    public void A(){
        System.out.println("这是A方法");
    }

    public int B(int i){
        return i+1;
    }

    public static void main(String[] args) throws Exception {

        Son son = new Son();
        Class<Son> sonClass = Son.class;
        Method a = sonClass.getMethod("A");
        a.invoke(son);

        Method b = sonClass.getMethod("B", int.class);
        Object invoke = b.invoke(son, 10);
        System.out.println(invoke);

    }

}

打印:
这是A方法
11
          //打印出所有方法,参数,返回类型

          Method[] methods = A.getDeclaredMethods();
          for (Method method : methods) {
            //依次获得方法的修饰符,返回类型和名称,外加方法中的参数
            String methodString = Modifier.toString(method.getModifiers()) + " " ; // 
             private static
            methodString += method.getReturnType().getSimpleName() + " "; // void
            methodString += method.getName() + "("; // staticMethod
            Class[] parameters = method.getParameterTypes();
            Parameter[] p = method.getParameters();

            for (Class parameter : parameters) {
                methodString += parameter.getSimpleName() + " " ; // String
            }
            methodString += ")";
            System.out.println(methodString);
           

 

3获取类的成员变量信息

两种主要方法

(1)获取类的所有公用(public)属性,包括其继承类的。

  public Field getField(String name) throws NoSuchFieldException, SecurityException

(2)获取类声明的所有属性,包含私有,公共,但不包含继承

 public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException

public class Son {

    private int i;
    public String add;

    public static void main(String[] args) throws Exception{
        Class<Son> sonClass = Son.class;
        Son son = new Son();
        Field add1 = sonClass.getField("add");
        add1.set(son,"111");
        System.out.println(son);

        Field i = sonClass.getDeclaredField("i");
        i.set(son,12);
        i.setAccessible(true);
        System.out.println(son);
    }


    @Override
    public String toString() {
        return "Son{" +
                "i=" + i +
                ", add='" + add + '\'' +
                '}';
    }
}

输出:
Son{i=0, add='111'}
Son{i=12, add='111'}

4创建数组

 Class<?> cls = null;
        try {
            cls = Class.forName("java.lang.String");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Object array = Array.newInstance(cls,25);
        //往数组里添加内容
        Array.set(array,0,"hello");
        Array.set(array,1,"Java");
        Array.set(array,2,"fuck");
        Array.set(array,3,"Scala");
        Array.set(array,4,"Clojure");
        //获取某一项的内容
        System.out.println(Array.get(array,3));

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值