Home > Java > javaTutorial > body text

Explain how to construct inner class objects and access objects in Java

高洛峰
Release: 2017-01-20 17:42:38
Original
1285 people have browsed it

Constructing internal class objects through reflection
First write a class containing internal classes under the javalang package:

package javalang;
 
public class Outer {
  public static class Inner1{}
}
Copy after login

Note that this class is public static, we will slowly add it later Remove these modifiers.

To create the Inner1 object through reflection, you must first obtain the Class object of Inner1. We write the main method in Outer:

public class Outer {
  public static class Inner1{}
   
  public static void main(String[] args) {
    System.out.println(Inner1.class);
  }
}
Copy after login

Output result:

class javalang.Outer$Inner1
Copy after login

Then we try to see if the class name is correct:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1"));
}
Copy after login

Run For a moment, that’s right. Then just use it to create objects. Creating objects relies on constructors. Does this class have a constructor method? We can write like this:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors().length);
}
Copy after login


Run it and output 1. It seems there is. Then take a 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]);
}
Copy after login


Output result: public javalang.Outer$Inner1(). This is the default construction method. So we can write like this:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors()[0].newInstance();
}
Copy after login

Output result: javalang.Outer$Inner1@ca0b6. This indicates that the execution was successful.

Next we remove the public keyword of Inner and then run it. The result is an error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
Copy after login

This means that the constructor method was not found. Really not? We change the main method back:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors().length);
}
Copy after login

Output result: 0. Is there really no constructor? Actually no, it's just that 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);
}
Copy after login

Output result: 1. This finds the construction method. Then we continue to call this constructor:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance());
}
Copy after login

Output result: javalang.Outer$Inner1@ca0b6. Now we can use reflection to construct objects of non-public inner classes.

Next, let’s remove the static keyword. At this time, an error was reported:
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments

What does this mean? We did not pass parameters when we called, and the error content was that the number of parameters was incorrect. So what parameters does this constructor have? Let’s change the code and take a look:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0]);
}
Copy after login

Output result: javalang.Outer$Inner1(javalang.Outer)

It turns out that the constructor requires an Outer type parameter. This is easy to do:

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance(new Outer()));
}
Copy after login

Output result:

javalang.Outer$Inner1@ca0b6
Copy after login

OK, that’s it. It seems that non-static inner classes do not have a default construction method, and an instance of an outer class needs to be passed as a parameter during construction.


Java: How to access an object
A headache for Java beginners is how to decide whether to define an object as a method variable or a member variable?

Beginners won’t care about this at first. But when the programs written become larger and larger and there are more and more classes, this kind of distress also arises.

But what I want to write here is: how to arrange an object as you wish so that you can access it at any time. Once you master this, you can freely decide where to place an object.

Here is a simple example:

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    // 这里如何获得 main() 方法中的 date 变量?
  }
}
Copy after login

As described in the anHourLater() method, you want to get the date one hour later. How to do it? There are several methods below.

(1) Parameter passing

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater(Date d) {
    Date anHourLater = new Date(d.getTime() + 3600000);
  }
}
Copy after login

(2) Defined as a member. Members can be accessed by all methods, and member initialization can be placed where they are defined or in any method.

public class AccessingObject {
   
  private static Date date;
   
  public static void main(String[] args) {
    date = new Date();
    anHourLater();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(date.getTime() + 3600000);
  }
}
Copy after login

(3) Put it in another class. In the following example, DateHolder.date can be accessed by all classes in the same package, not just the AccessingObject class.

public class AccessingObject {
   
  public static void main(String[] args) {
    DateHolder.date = new Date();
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater() {
    Date anHourLater = new Date(DateHolder.date.getTime() + 3600000);
  }
}
   
class DateHolder {
  public static Date date;
}
Copy after login

Comparing these three examples, the first two can only be used inside the class, which is relatively safe. If you don't want this object to be modified directly by other classes, don't use the third method.

The difference between the first method and the second method is: if an object is only used in a method, then when the method is executed, the object can be easily recycled (note that it is not recycled immediately ). If defined as a member of a class, the object will be recycled only after the class in which it is located is recycled. Obviously, the first method is the most resource-saving, and we should try to use the first method.

Looking back at these three examples, if the main() method wants to obtain the time after one hour obtained in the anHourLater() method, it also has several corresponding methods. There is no need to change the last two examples, the date object can be accessed directly; in the first example, there are two modification methods:

(1) As the return value

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    Date anHourLater = anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static Date anHourLater(Date d) {
    return new Date(d.getTime() + 3600000);
  }
}
Copy after login

(2) Directly modify the content of the parameters

public class AccessingObject {
   
  public static void main(String[] args) {
    Date date = new Date();
    anHourLater(date);
  }
   
  // 获得 date 对象一小时后的时间
  private static void anHourLater(Date d) {
    d.setTime(d.getTime() + 3600000);
  }
}
Copy after login

The second method should be used with caution, because it can be used casually Something is wrong, you don't know whether the caller of the method likes what you do.

For more articles explaining how to construct internal class objects and access objects in Java, please pay attention to the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template