JAVA basic reflection - detailed (personally think it should be fairly clear)

Reflection plays a pivotal role in JAVA, reflection can help us create objects dynamically at runtime.

What is dynamic creation of objects at runtime?

RTTI is a compile-time method, and reflection is a run-time method, so in order to better understand reflection, we must first understand RTTI. Before that, we must know how java is a file from loading to execution. Confused concepts at compile time and run time.

1.java file execution process:

1. Source files: We write .java files

2. Compile: Compile the java file into a .class binary bytecode file (at the same time, a class file with the same name will be generated to save the Class object)

3. Run: Pass the generated class file to the jvm.

4. Class loading: The class loading process is more complicated, so I will briefly talk about it here.

(1) Loading: Load
the bytecode file into the memory through the class loader (java is dynamically loaded, and the class will only be loaded when it is used).

(2) Connection

  • Validation: To ensure that the bytecode file conforms to the JVM specification, it is validated.
  • Preparation: allocate memory for class variables and assign initial values ​​(the initial value is the constant defined value in the JVM)
  • Parse: replace symbolic references with direct references

(3) Initialization: Initialize static variables, and the order of execution is top-to-bottom.

5. Get started

2.Class object:

The Class object is the basis of our reflection operation and is a very important part. When compiling, a class file with the same name will be generated and the Class object will be saved into it.

The Class object contains class-related information, in other words, the channel through which we obtain information through reflection is the Class object.

The methods provided by the Class class can be found in the relevant documentation.

3. What is RTTI?

The concept of RTTI first appeared in C++, and was later put forward by Bruce Eckel in thinking in java about rtti in java, but there is no related concept of RTTI in the java document, and there are different opinions.

The role of RTTI : Identifying an object type at runtime requires that the object type must be known at compile time.

RTTI (Run-Time Type Identification), through the run-time type information program can use the pointers or references of the base class to check the actual derived type of the objects that these pointers or references refer to.

--Baidu Encyclopedia

This sentence in java is simply to see which subclass the base class object actually points to in polymorphism.

Take a chestnut:

The base class is Animal, which has a method showName and a method to print its own class name.

Subclasses are dog, cat, fish.

When we call via polymorphism:

Animal a = new cat();//会触发向上转型机制,将对象都作为Animal对象.

a.showName();//此时调用的cat的showName,我们在使用的时候 需要知道现在Animal a对象实际上指向的是谁, 这时候就需要RTTI发挥作用.

RTTI的作用:在运行时识别一个对象类型.

4. What is reflection?

Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fields, methods, and constructors to operate on their underlying counterparts on objects, within security restrictions.

The API accommodates applications that need access to either the public members of a target object (based on its runtime class) or the members declared by a given class. Programs can suppress default reflective access control. For more information, see the Reflection documentation.

From java official documentation

In short, we can obtain member information in the program at runtime through reflection.

effect:

From the above, it seems that there is no intuitive difference. When the program runs, a byte stream is obtained in the network and then told that it is a class object, or a file is obtained from the disk, which is class information. The creation and acquisition of objects can only be done through reflection, because the program has passed the compilation stage at this time.

The most important use of reflection is to develop various general frameworks.

For example, in the IOC control inversion in the most commonly used Spring framework, javabeans are automatically loaded, and different initialization operations are performed according to XML. The implementation is based on reflection, and the required objects are dynamically loaded after we compile.

The use of reflection:
Reflection can be used to determine the class to which any object belongs, obtain the Class object, construct any object, and call an object.

Step 1: Get the Class object (all the information we need is in this object, so it was said earlier that this object is the core.)

Method 1: Via forName

Class.forName():方法返回一个Class对象

forName(String className)//字符串为类名
 
forName(String name, boolean initialize, ClassLoader loader) //类名称,是否进行初始化,选择加载器.

实际上通过forName(String className)获取类对象时相当于调用了
Class.forName(className, true, currentLoader)  自动进行初始化,并且加载器选择的是当前类定义的加载器.

Method 2: Obtain directly through the class

Class<?> clz= String.class//通过.class方法 获取Class对象

Method 3: Get Class by object

TestA A =new TestA();

A.getClass();

Step 2: Use the Class object

判断类实例:
可以使用 instanceof

我们现在也可以使用获取Class对象后中的isInstance();方法进行判断

创建实例:

(1)使用Class对象的newInstance()方法来创建Class对象对应类的实例。

Class<?> c = String.class;//获取Class对象
Object str = c.newInstance();//通过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");
System.out.println(obj);


上面说完构造 下边说获取:

    方法获取:
public Method[] getDeclaredMethods() throws SecurityException
//获取所有声明方法,但是不包括继承


Class<?> c = TestA.class;//获取对象
Method[] methods = c.getDeclaredMethods();//通过方法返回Method数组
for(Method method:methods){
    System.out.println(method);//通过Foreach循环打印,println在没有指定的时候会隐式调用toString方法,大家可以自己重写试一下.
}

//输出结果:
public java.lang.String TestA.toString()
public int TestA.getA()
public void TestA.setA(int)     

其他获取方法使用基本相同,在此不多说,有兴趣可以查看官方文档.


方法的调用:
    当我们在上边获取了一个方法之后,我们可以通过invoke方法对其进行调用.
public class test1 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> klass = methodClass.class;
        //创建methodClass的实例
        Object obj = klass.newInstance();
        //获取methodClass类的add方法
        Method method = klass.getMethod("add",int.class,int.class);
        //调用method对应的方法 => add(1,4)
        Object result = method.invoke(obj,1,4);
        System.out.println(result);
    }
}
class methodClass {
    public final int fuck = 3;
    public int add(int a,int b) {
        return a+b;
    }
    public int sub(int a,int b) {
        return a+b;
    }
}
    //这里代码来自sczyh30具体地址会放到下面网页参考.

利用反射创建数组:

public static void testArray() throws ClassNotFoundException {
    Class<?> cls = Class.forName("java.lang.String");//获取对象
    Object array = Array.newInstance(cls,25);//传入cls对象,数组长度.
    //往数组里添加内容
    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));
}
//这里代码来自sczyh30具体地址会放到下面网页参考.

这里主要借助反射中的Array类:
public static Object newInstance(Class<?> componentType, int length)
    throws NegativeArraySizeException {
    return newArray(componentType, length);
}
//componentType是一个需要构造的类型,就是我们穿进去的cls类型,后边是指定的长度

public static void set(Object array,
                   int index,
                   Object value)
            throws IllegalArgumentException,
                   ArrayIndexOutOfBoundsException
通过Array提供的set方法进行数组设置, 传入数组对象,下标,数值.
下边get同理.

References:

[1]:https://www.sczyh30.com/posts/Java/java-reflection-1/#%E4%B8%80%E3%80%81%E5%9B%9E%E9%A1%BE%EF%BC%9A%E4%BB%80%E4%B9%88%E6%98%AF%E5%8F%8D%E5%B0%84%EF%BC%9F
[2]:Thinking in java page 313-335

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325251644&siteId=291194637