Constructing inner class objects by reflection
First, write a class containing the inner class under the Javalang package:
Package Javalang;
public class Outer {public
static class inner1{}
}
Note that this class is public static, and we slowly remove these modifiers later.
To create a Inner1 object by reflection, you first get the Inner1 Class object. We write the main method in the Outer:
public class Outer {public
static class inner1{} public
static void Main (string[] args) {
System.out.println (Inner1.class);
}
Output results:
Class Javalang. Outer$inner1
And then we'll try this class name right:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 "));
}
Run it, yes. Then it is used to create the object. You create objects by constructing methods. Does this class have a construction method? We can write this:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 "). GetConstructors (). length);
Run it, output 1. It seems there is. And then look at what this construction method looks like:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 "). GetConstructors () [0]);
}
Output result: Public Javalang. Outer$inner1 (). This is the default construction method. So we can write this:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. GetConstructors () [0].newinstance ();
}
Output result: Javalang. Outer$inner1@ca0b6. This shows that the execution was successful.
Next we remove the Inner public keyword and then run it. The result is an error:
Exception in thread "main" java.lang.arrayindexoutofboundsexception:0
This indicates that no construction method was found. No, really? We'll change the main method back:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. GetConstructors (). length);
Output Result: 0. Is there really no way to construct it? Not really, but the construction method is not public. At this time we must use Getdeclaredconstructors () to obtain:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. Getdeclaredconstructors (). length);
Output result: 1. This finds the construction method. Then we continue to call this construction method:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. Getdeclaredconstructors () [0].newinstance ());
}
Output result: Javalang. Outer$inner1@ca0b6. Now we can use reflection to construct an object that is not exposed to the inner class.
Next, we'll remove the static keyword. This time the error:
Exception in thread "main" java.lang.IllegalArgumentException:wrong number of arguments
What does that mean? We call without passing arguments, and the error is that the number of arguments is incorrect. So what are the parameters of this construction method? Let's change the code to see:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. Getdeclaredconstructors () [0]);
}
Output result: Javalang. Outer$inner1 (Javalang. Outer)
The original construction method requires a Outer type parameter. This is good to do:
public static void Main (string[] args) throws Exception {
System.out.println (class.forname ("Javalang"). Outer$inner1 ")
. Getdeclaredconstructors () [0].newinstance (New Outer ());
}
Output results:
Javalang. Outer$inner1@ca0b6
OK, that's it. It appears that non-static internal classes do not have a default construction method, which requires that an instance of an external class be passed as an argument.
Java: How to access an object
One of the headaches for Java beginners is how do you decide to define an object as a method variable or as a member variable?
In the beginning, scholars will not care about this. But when the process of writing more and more, the class more and more, this kind of distress also arises.
But what I want to write here is: How to arrange an object at will, so that you can access it anytime. With this in mind, you are free to decide where to put an object.
Here's a simple example:
public class Accessingobject {public
static void Main (string[] args) {
date date = new Date ();
}
Get the Date object one hour later
private static void Anhourlater () {
//How do I get the date variable in the main () method here?
}
}
As described in the Anhourlater () method, you want to get date one hour later. What do we do? There are several ways to do this.
(1) Parameter transfer
public class Accessingobject {public
static void Main (string[] args) {
date date = new Date ();
Anhourlater (date);
Gets the Date object one hour later
private static void Anhourlater (Date d) {
date anhourlater = new Date (D.gettime () + 3600000);
}
}
(2) defined as a member. Members can be accessed by all methods, and the initialization of a member can be placed in a defined place or in any method.
public class Accessingobject {
private static date date;
public static void Main (string[] args) {
date = new Date ();
Anhourlater ();
}
Gets the time of the date object in one hour
private static void Anhourlater () {
date anhourlater = new Date (Date.gettime () + 3600000); c20/>}
}
(3) Put it in another class. In the following example, Dateholder.date can be accessed by all classes in the same package, not limited to the Accessingobject class.
public class Accessingobject {public
static void Main (string[] args) {
dateholder.date = new Date ();
}
Gets the time of the date object in one hour
private static void Anhourlater () {
date anhourlater = new Date (DateHolder.date.getTime () + 3 600000);
}
Class Dateholder {public
static date date;
}
These three examples compare, the first two can only be used within the class, relatively safe. If you don't want this object to be directly modified by another class, don't use the third way.
The difference between the first and the second is that if an object is used only in a method, then when the method is done, the object can be easily recycled (note that it is not immediately recycled). If defined as a member of a class, the object is reclaimed only after the class in which it resides is reclaimed. Obviously, the first way is to conserve resources, and we should try to use the first way.
Looking back at these three examples, if the main () method obtains an hour after the Anhourlater () method, it also has several corresponding ways. The latter two examples do not have to change, the date object is directly accessible, the first example, there are two ways to modify:
(1) as the return value
public class Accessingobject {public
static void Main (string[] args) {
date date = new Date ();
Date Anhourlater = Anhourlater (date);
}
Gets the Date object one hour later
private static date Anhourlater (Date D) {return
new date (D.gettime () + 3600000);
}
(2) directly modify the contents of the parameter
public class Accessingobject {public
static void Main (string[] args) {
date date = new Date ();
Anhourlater (date);
Gets the time of the date object after one hour
private static void Anhourlater (Date d) {
d.settime (d.gettime () + 3600000);
}
The second method should be used with caution, because it is not right to move other people's things, you do not know the method of the caller likes you to do so.