[Java] Pour connaître les informations de type des paramètres de type à l'exécution

0. Conclusion d'abord

--Héritage de classe avec le paramètre de type T


1. Défi

Le type des éléments du tableau peut être trouvé plus tard avec ʻarray.getClass (). GetComponentType () `, Il est difficile de faire la même chose avec des listes telles que ArrayList et LinkedList!


2. Public cible

--Les personnes qui ont utilisé la classe Class en java --Les personnes intéressées par les paramètres de type


3. Mauvais exemple


Préparation

class Hoge
{
    public static void main(String[] args)
    {
        ArrayList<Number> inteList = new ArrayList<>();
        System.out.println(new ParamGetter(inteList).get());
        //Obtention de la classe ParamGetter()Dans la méthode
        //Je veux afficher "Numéro", etc.
    }
}

3.1 T.class n'est pas possible

class ParamGetter
{
    Class paramClass;
    <T> ParamGetter(List<T> list)
    {
        this.paramClass = T.class;
        //× C'est NG
    }
    Class get(){return paramClass;}
}

3.2 La réflexion échoue [1]

//(Pour ceux qui ont réfléchi)
class ParamGetter
{
    Type paramType;
    <T> ParamGetter(List<T> list)
    {
        this.paramType = ((ParameterizedType)new ArrayList<T>(){}.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }
    Type get(){return paramType;}
}

Résultat: "T" s'affiche La même chose s'applique à la méthode [2] utilisant la méthode getGenericType () de la classe Field.


3.3 Impossible d'organiser avec toArray ()

class ParamGetter
{
    Object array;
    <T>ParamGetter(List<T> list)
    {
        this.array = (T[])list.toArray();
        //☆System.out.println((T[])list.toArray());
    }

    Type get() throws NoSuchFieldException, SecurityException
    {
        return this.array.getClass().getComponentType();
    }
}

Résultat (principal): "class java.lang.Object" s'affiche.

<!--

Serpentin L'idée de «prendre un élément d'une liste et d'examiner son type» est peut-être possible, mais elle est en fait inappropriée.

--De List <Number>, ʻInteger [] peut être fait, mais Number [] `ne le peut pas.


4. Cause fondamentale

Les informations de type disparaissent au stade du passage à la méthode


Dans 3.3, d'abord, l'argument factice de type List <T> est passé à l'argument réel de type ʻArrayList . Ensuite, il est converti en un tableau de type «T» et stocké dans un champ de type «Objet». Ensuite, quand get ()` est appelé, il trouve le "type d'exécution" (type de tableau) et vérifie le type des éléments de ce tableau.


Le résultat est ʻObject`, Au lieu de «T» = «Number», cela signifie «T» = «Object».


En fait, quand j'exécute le code de ☆, il s'affiche qu'il est de type ʻObject [] . → Après tout T []= ʻObjet []

System.out.println((T[])list.toArray());//Object[]Il sort avec un moule.

À partir de là, on peut voir que les informations de paramètre de type ont disparu lors de leur passage en argument. En fait effacé au moment de la compilation (devient le type le plus abstrait pouvant être reçu) [3]


5. Solution

Ce qui disparaît à l'exécution ne peut pas être supprimé même par réflexion (la réflexion est une technologie à l'exécution [4]) →


5.1 Remplacer le paramètre de type par l'argument

class Hoge<T> Survie de Fuga Fuga as
new Hoge(); × Paramètres de type des méthodes d'instance
new Hoge<Fuga>(); Paramètres de type de la classe[5]
new Hoge(Fuga.class) Argument de type de classe

△ ・ ・ ・ Ce n'est pas impossible, mais ce sera redondant.


5.2 ArrayList<T>
ArrayList_<T>

Chose que vous voulez faire: new ArrayList_ <Number> (Object ...); new ArrayList <Number> (Object ...); et Donnez-lui presque la même signification Et rendre Number disponible au moment de l'exécution


A presque la même signification → Réalisable par héritage Ecrire en référence au commentaire de M. saka1029 dans cet article

public class ArrayList_<T> extends ArrayList<T> {

    public final Class<?> clazz;

    public ArrayList_(T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
                "Ne spécifiez pas d'argument factice");
        clazz = dummy.getClass().getComponentType();
    }

    public Class getComponentClass() {
        return clazz;
    }
}


6 (Bonus) Active new Hoge <t.getClass ()>

Une instance de type générique «Hoge » ne peut pas être créée à partir d'une variable de type «Classe ».


En bref, new Hoge <t.getClass ()> ne peut pas être fait. Si vous l'écrivez dans la méthode, il est possible dans une certaine mesure en tant que new Hoge <?>, Hoge<t.getClass()>.getClass().getDeclaredConstructor().newInstance() Il n'est pas possible de créer une instance de type générique n'importe où.


Si vous voulez faire cela, passez une variable de type Classe <?> Comme argument.

public class ArrayList_<T> extends ArrayList<T> {

    public final Class<?> clazz;

    public ArrayList_(T... dummy) {
        if (dummy.length > 0)
            throw new IllegalArgumentException(
                "Ne spécifiez pas d'argument factice");
        clazz = dummy.getClass().getComponentType();
    }

    public ArrayList_(Class<T> clazz)//Ajoute ça
    {
        this.clazz = clazz;
    }

    public Class getComponentClass() {
        return clazz;
    }
}

référence

[1]http://unageanu.hatenablog.com/entry/20071105/1194264963 [2]https://codeday.me/jp/qa/20181216/16785.html [3]https://qiita.com/pebblip/items/1206f866980f2ff91e77 Le "type le plus abstrait qui peut être reçu" dans le texte signifie la "limite supérieure" dans [3]. [4]https://java.keicode.com/lang/reflection.php [5] L'argument de M. saka1029 dans cet article Autres: https://java-beginner.com/thread-thread-and-runnable/

Recommended Posts

[Java] Pour connaître les informations de type des paramètres de type à l'exécution
Sortie du livre "Introduction à Java"
[Java] Faites attention au type de clé de la carte
Java Bienvenue dans le marais des tableaux bidimensionnels
[Java] Comment obtenir l'URL de la source de transition
Comment écrire Scala du point de vue de Java
[Java] Comment obtenir la valeur maximale de HashMap
Je veux connaître la réponse de l'application Janken
J'étais accro à getXxxx de ResultSet car c'est un type primitif (Java)
[Rails] Comment obtenir le contenu des paramètres forts
Java: utilisez Stream pour trier le contenu d'une collection
J'ai essayé de résumer les bases de kotlin et java
Accédez à l'abréviation à partir de 5 exemples de listes Java en italique
20190803_Java & k8s sur Azure L'histoire d'aller au festival
Commande pour vérifier le nombre et l'état des threads Java
Comment obtenir les informations les plus longues de Twitter à partir du 12/12/2016
Comment dériver le dernier jour du mois en Java
L'histoire de la transmission de Java à Heroku à l'aide du pipeline BitBucket
Assurez-vous de comparer le résultat Java compareTo avec 0
Réintroduction à Java for Humanities 0: Comprendre l'acte de programmation
Que ce soit pour faire du côté serveur au moment de la reconstruction du système avec Kotlin ou Java
Entrée dans la console Java
Connaître la commodité de Docker (-compose) maintenant (liste d'informations auxquelles j'ai fait référence lors de son utilisation)
[Java] Divers résumés joints aux chefs de classe et aux membres
Examiner les informations système de l'environnement d'exploitation AWS Lambda en Java
Je veux comprendre le flux des paramètres de demande de traitement Spring
Java Convertit des codes de caractères disparates en un même code de caractère à la fois
J'ai essayé le type d'entrée / sortie de Java Lambda ~ Map edition ~
Vous voulez savoir ce que Ruby n est la puissance de 2? (Jugement de puissance de 2)
La milliseconde définie dans /lib/calendars.properties de Java jre est UTC
De Java naissant (3 ans) à Node.js (4 ans). Et l'impression de retourner à Java
J'ai essayé de résumer les méthodes de Java String et StringBuilder
[Java] Comment convertir du type String en type Path et obtenir le chemin
Comment vérifier le contenu de la chaîne de caractères java de longueur fixe
Comment obtenir la longueur d'un fichier audio avec Java
Comment incrémenter la valeur de Map sur une ligne en Java
[Java] Supprimer les éléments de la liste
[java8] Pour comprendre l'API Stream
Compilez Java sur l'invite de commande
[Édition Java] Histoire de la sérialisation
[Java] Zones de données d'exécution de JVM
Bienvenue dans le marais des bibliothèques Java! !!
[Java] Comparaison correcte du type String
La route de JavaScript à Java
L'origine des expressions Java lambda
Comment utiliser le type enum Java
expression régulière java-pas de perte de savoir-
[Java] Comment récupérer les paramètres passés du html côté serveur
L'histoire de l'oubli de fermer un fichier en Java et de l'échec
[Servlet Java] La route de Senri est également une étape vers la première
Je veux connaître le JSP du portlet ouvert lors du développement de Liferay
Obtenez le type d'un élément d'un tableau pour déterminer s'il s'agit d'un tableau
Comment savoir quelle version Java d'un fichier de classe a été compilée
Raison pour ajouter L au nombre à mettre en type long Java
[Java] Comment accéder au début d'une chaîne spécifique à l'aide de la classe String
Comment trouver le nombre total de pages lors de la pagination en Java
Comment changer la valeur d'une variable à un point d'arrêt dans intelliJ
Comment obtenir le chemin absolu d'un répertoire s'exécutant en Java
[Cas d'amélioration Java] Comment atteindre la limite de l'auto-apprentissage et au-delà