Maison > Java > javaDidacticiel > le corps du texte

Expliquer comment construire des objets de classe interne et accéder aux objets en Java

高洛峰
Libérer: 2017-01-20 17:42:38
original
1279 Les gens l'ont consulté

Construire des objets de classe internes par réflexion
Écrivez d'abord une classe contenant des classes internes sous le package javalang :

package javalang;
 
public class Outer {
  public static class Inner1{}
}
Copier après la connexion

Notez que cette classe est publique statique, nous allons ralentir vers le bas plus tard Supprimez ces modificateurs lentement.

Pour créer un objet Inner1 par réflexion, vous devez d'abord obtenir l'objet Class d'Inner1. Nous écrivons la méthode principale dans Outer :

public class Outer {
  public static class Inner1{}
   
  public static void main(String[] args) {
    System.out.println(Inner1.class);
  }
}
Copier après la connexion

Résultat de sortie :

class javalang.Outer$Inner1
Copier après la connexion

Ensuite, nous essayons de voir si le nom de la classe est correct :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1"));
}
Copier après la connexion

Exécutez-le, c'est vrai. Ensuite, utilisez-le simplement pour créer des objets. La création d'objets repose sur des constructeurs. Cette classe a-t-elle une méthode constructeur ? On peut écrire :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors().length);
}
Copier après la connexion


Exécutez-le et sortez 1. Il semble que ce soit le cas. Jetez ensuite un œil à ce à quoi ressemble cette méthode de construction :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1").getConstructors()[0]);
}
Copier après la connexion


Résultat de sortie : public javalang.Outer$Inner1(). Il s'agit de la méthode de construction par défaut. On peut donc écrire comme ceci :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors()[0].newInstance();
}
Copier après la connexion

Résultat de sortie : javalang.Outer$Inner1@ca0b6. Cela indique que l'exécution a réussi.

Ensuite, nous supprimons le mot-clé public d'Inner et l'exécutons à nouveau. Le résultat est une erreur :

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
Copier après la connexion

Cela signifie que la méthode de construction n'a pas été trouvée. Vraiment pas ? Nous modifions la méthode principale :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getConstructors().length);
}
Copier après la connexion

Résultat de sortie : 0. Il n'y a vraiment pas de constructeur ? En fait non, c'est juste que la méthode de construction n'est pas publique. À ce stade, nous devons utiliser getDeclaredConstructors() pour obtenir :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors().length);
}
Copier après la connexion

Résultat de sortie : 1. On retrouve ainsi la méthode de construction. Ensuite, nous continuons à appeler ce constructeur :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance());
}
Copier après la connexion

Résultat de sortie : javalang.Outer$Inner1@ca0b6. Nous pouvons désormais utiliser la réflexion pour construire des objets de classes internes non publiques.

Ensuite, supprimons le mot-clé statique. À ce moment-là, une erreur a été signalée :
Exception dans le thread "main" java.lang.IllegalArgumentException : mauvais nombre d'arguments

Qu'est-ce que cela signifie ? Nous n'avons pas transmis de paramètres lors de notre appel et le contenu de l'erreur était que le nombre de paramètres était incorrect. Alors, quels sont les paramètres de ce constructeur ? Modifions le code et jetons un œil :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0]);
}
Copier après la connexion

Résultat de sortie : javalang.Outer$Inner1(javalang.Outer)

Il s'avère que le constructeur nécessite un paramètre de type Outer. C'est facile à faire :

public static void main(String[] args) throws Exception {
  System.out.println(Class.forName("javalang.Outer$Inner1")
      .getDeclaredConstructors()[0].newInstance(new Outer()));
}
Copier après la connexion

Résultat de sortie :

javalang.Outer$Inner1@ca0b6
Copier après la connexion

OK, c'est tout. Il semble que les classes internes non statiques n'aient pas de méthode de construction par défaut et qu'une instance d'une classe externe doive être passée en paramètre lors de la construction.


Java : Comment accéder à un objet
Un casse-tête pour les débutants Java est de savoir comment décider s'il faut définir un objet comme variable de méthode ou comme variable membre ?

Les débutants ne s'en soucieront pas au début. Mais lorsque les programmes écrits deviennent de plus en plus grands et qu'il y a de plus en plus de classes, ce genre de détresse surgit aussi.

Mais ce que je veux écrire ici, c'est : comment agencer un objet comme on l'entend pour pouvoir y accéder à tout moment. Une fois que vous maîtrisez cela, vous pouvez décider librement où placer un objet.

Voici un exemple simple :

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

Comme décrit dans la méthode anHourLater(), vous souhaitez obtenir l'heure une heure après la date. Ce qu'il faut faire? Il existe plusieurs méthodes ci-dessous.

(1) Passage de paramètres

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);
  }
}
Copier après la connexion

(2) Défini en tant que membre. Les membres sont accessibles par toutes les méthodes et l'initialisation des membres peut être placée là où ils sont définis ou dans n'importe quelle méthode.

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);
  }
}
Copier après la connexion

(3) Mettez-le dans une autre classe. Dans l'exemple suivant, DateHolder.date est accessible à toutes les classes du même package, pas seulement à la classe AccessingObject.

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;
}
Copier après la connexion

En comparant ces trois exemples, les deux premiers ne peuvent être utilisés qu'à l'intérieur de la classe et sont relativement sûrs. Si vous ne souhaitez pas que cet objet soit modifié directement par d'autres classes, n'utilisez pas la troisième méthode.

La différence entre la première méthode et la deuxième méthode est la suivante : si un objet est uniquement utilisé dans une méthode, alors lorsque la méthode est exécutée, l'objet peut être facilement recyclé (attention, il n'est pas recyclé immédiatement) . S'il est défini comme membre d'une classe, l'objet ne sera recyclé qu'après le recyclage de la classe dans laquelle il se trouve. De toute évidence, la première méthode est la plus économe en ressources, et nous devrions essayer d’utiliser la première méthode.

En repensant à ces trois exemples, si la méthode main() veut obtenir l'heure une heure plus tard obtenue dans la méthode anHourLater(), elle a également plusieurs manières correspondantes. Il n'est pas nécessaire de modifier les deux derniers exemples, l'objet date est accessible directement ; dans le premier exemple, il existe deux méthodes de modification :

(1) comme valeur de retour

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);
  }
}
Copier après la connexion

(2) Modifier directement le contenu des paramètres

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);
  }
}
Copier après la connexion

La deuxième méthode doit être utilisée avec prudence, car c'est mal de toucher aux choses des autres avec désinvolture. Vous ne savez pas si l'appelant de la méthode l'aime ou non.

Pour plus d'articles expliquant comment construire des objets de classe internes et accéder aux objets en Java, veuillez faire attention au site Web PHP chinois !

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal