If someone asks you about Java's reflection again, throw this article to him

Keywords: Programming Java JSON network Apache

In Java, not all types of information can be identified at the compilation stage. Some types of information need to be determined at runtime. This mechanism is called RTTI. In English, it is called Run-Time Type Identification. Runtime type recognition. Does it taste like "knowing and doing as one"?Runtime type recognition is mainly implemented by Class classes.

In our daily learning and work, there are some knowledge that we can acquire when we are reading; but some knowledge is not, and we need to get the true knowledge when we are practicing it - this may be the "knowledge and practice are in one" advocated by Wang Yangming.

01, Class Class

In Java, we often use the "class" (c initially lowercase) keyword to define a class that is an abstraction of a class of objects.If you say Wang Er is a well-known author on the Internet, we can simply define the author class:

package com.cmower.java_demo.fifteen;

class Author {
	private String pen_name;
	private String real_name;
}

Now, what if we want to know some information about the Writer class itself (such as its name)?At this point, you need to use a "Class" (C with capital letters) class that contains information about the class.See the following code:

public class Test {
	public static void main (String [] args) {
		Author wanger = new Author();
		Class c1 = wanger.getClass();
		System.out.println(c1.getName());
		//Output com.cmower.java_demo.fifteen.Author
	}
}

Once we have created the author object wanger, we can get the lass object from wanger.getClass(), and the Class name of the Wanger object from c1.getName().

Imagine that after five years of intentional practice, Wang Er was promoted from a writer enthusiast to a writer.Let's pretend with code:

package com.cmower.java_demo.fifteen;

class Author {
	private String pen_name;
	private String real_name;
}

class Writer extends Author {
	private String honour;
}

public class Test {
	public static void main (String [] args) {
		Author wanger = new Writer();
		Class c1 = wanger.getClass();
		System.out.println(c1.getName());
		//Output com.cmower.java_demo.fifteen.Writer
	}
}

In the example above, even if we converted the Writer object reference wanger up to Author, wanger's lass object type is still Writer (determined by the output).This means that Java can automatically recognize type information at runtime without losing the real type information (Writer) of wanger because the reference type of wanger is Author.How does Java do this?

When Java creates an object of a class, such as a Writer class object, Java checks to see if there is a corresponding Class object in memory.If there is no corresponding Class object in memory, Java looks for the definition of the Writer class in the.Class file and loads the Class object of the Writer class.

Once the Class object is loaded successfully, you can use it to create all objects of this type.That is, each object will have a corresponding Class object at run time, which contains the type information of the object.Therefore, we can know the "real" type of an object through the Class object, and it will not be lost because of the upward transition.

02. Other ways to get Class objects

When using the getClass() method to get a Class object of a class, we must first get the object of that class, such as the wanger mentioned above.If we haven't previously acquired objects of this class, we need to acquire Class objects of the class in two other ways:

Class c2 = Writer.class;
System.out.println(c2.getName());

try {
	Class c3 = Class.forName("com.cmower.java_demo.fifteen.Writer");
	System.out.println(c3.getName());
} catch (ClassNotFoundException e) {
	e.printStackTrace();
}

1) When using.Class to obtain a Class object, the Class object is not automatically initialized, and initialization is delayed until the first reference to a static method or a non-final static field is made.This is not only simpler but also safer because it is checked at compile time (and therefore does not need to be placed in a try statement block).

2) Class.forName automatically initializes the Class object, but requires the class name to be specified and placed in the try statement block.

03. Common methods provided by Class class

The Class class provides us with some very useful methods, such as getName() to return the class name and getPackage() to return the package name of the class.

We can also use the newInstance() method provided by the Class class to create objects of the corresponding class, such as:

Class c2 = Writer.class;
System.out.println(c2.getName());

try {
	Writer wangsan = (Writer) c2.newInstance();
	System.out.println(wangsan);
	// Output: com.cmower.java_demo.fifteen.Writer@7852e922
} catch (InstantiationException | IllegalAccessException e1) {
	e1.printStackTrace();
}

Since we did not use generics when creating the Class object c2, the object type returned by newInstance() needs to be strongly converted to Writer.On this basis, we can make improvements as follows:

Class<Writer> c4 = Writer.class;
System.out.println(c4.getName());

try {
	Writer wangsan = c4.newInstance();
	System.out.println(wangsan);
	// Output: com.cmower.java_demo.fifteen.Writer@7852e922
} catch (InstantiationException | IllegalAccessException e1) {
	e1.printStackTrace();
}

04. Reflection

We can also get all public-modified fields through getFields(), and return all public-modified methods through getMethods().

Even more fields are available through getDeclaredFields(), including public, protected, default (package) access, and private fields, but not inherited fields.Correspondingly, getDeclaredMethods() is used to get more methods.Examples are as follows:

package com.cmower.java_demo.fifteen;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class Author {
	private String pen_name;
	private String real_name;
}

class Writer extends Author {
	private String honour;

	private void makeMoney() {
		System.out.println("Lots and lots of money");
	}
}

public class Test {
	public static void main(String[] args) {

		Class<Writer> c4 = Writer.class;
		System.out.println(c4.getName());

		try {
			Writer wangsan = c4.newInstance();
			System.out.println(wangsan);

			Field[] fields = c4.getDeclaredFields();
			for (Field field : fields) {
				System.out.println(field.getName());
			}

			Method[] methods = c4.getDeclaredMethods();
			for (Method method : methods) {
				System.out.println(method.getName());
			}
		} catch (InstantiationException | IllegalAccessException e1) {
			e1.printStackTrace();
		}

	}
}

The example above actually involves reflection, and Field, Method (and Constructor not mentioned in the example) all come from the java.lang.reflect class library.The Class class, along with the java.lang.reflect class library, supports the concept of reflection.

Reflection is sometimes required when we need to read a string of byte codes from a disk file or a network file and convert it into a class.The most common example is reflecting a string of JSON strings (which may have an initial form in a network transmission as an array of bytes) as objects of the corresponding type.

FastJSON provided by Alibaba provides toJSONString() and parseObject() methods to convert Java objects to and from JSON.The toJSONString method is called to convert the object to a JSON string, and the parseObject method, in turn, converts the JSON string to an object.Inside FastJSON is the reflection mechanism.

package com.cmower.common.util;

import java.io.UnsupportedEncodingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.fastjson.JSON;

@SuppressWarnings("all")
public class JsonUtil {
	private static Log logger = LogFactory.getLog("json");

	public static byte[] objectToByte(Object obj) throws UnsupportedEncodingException {
		String jsonStr = JSON.toJSONString(obj);
		logger.debug("Data after serialization:" + jsonStr);
		return jsonStr.getBytes("UTF-8");
	}

	public static <T> T byteToObject(byte[] data, Class<T> obj) throws UnsupportedEncodingException {
		String objectString = new String(data, "UTF-8");
		logger.debug("Deserialized data : " + objectString);
		return JSON.parseObject(objectString, obj);
	}
	
	public static <T> Object stringToObject(String data, Class<T> obj) throws UnsupportedEncodingException {
		logger.debug("Deserialized data : " + data);
		return JSON.parseObject(data, obj);
	}
}

05. Summary

In order to complete this article, I intentionally and Silent Wang Er Exchange Group A technical expert chatted and asked him some silly questions: "'What does runtime mean?"Do you stand at the angle of a Java virtual machine or a programmer?

He gave me a good explanation and inspiration, and I can't help feeling very ashamed that as an older Java learner, my theoretical knowledge is so weak that it's terrible - don't you know if you have any such confusion?

But the good thing about writing is that as I explain to my readers how Java recognizes type information at runtime, my ideas become clearer and clearer - a great way to improve yourself!

Last: Java Exception Handling: Cover the Program

Next: Java enumeration: small enum, elegant and clean

WeChat searched for "Silence King II" public number and responded to "Free Video" to get 500G high quality teaching videos after paying attention to it. Categorized).

Posted by nystateofmind27 on Fri, 08 Nov 2019 15:51:56 -0800