2017-10-11 4 views
0

Celui-ci va être difficile à expliquer mais je vais essayer. J'essaye de créer dynamiquement une table de base de données qui imite des objets de Java. Il aura donc chaque colonne pour chaque champ défini dans un objet particulier. Ces objets Java peuvent avoir des primitives définies, des tableaux et d'autres objets à l'intérieur de ceux-ci. Je génère l'instruction SQLite create à partir d'une fonction récursive que j'ai créée. Plus spécifiquement, cette fonction créera les paires de colonnes/types dans la requête DB create table.Java déterminant la taille d'un tableau dans un tableau inconnu par réflexion

Le problème que je rencontre est de tenter de déterminer la taille d'un tableau. Voici ma fonction qui génère les paires colonne/type.

public String processColumnData(String topicName) 
{ 
    Field fieldList[] = null; 
    String query = ""; 

    try 
    { 
     fieldList = Class.forName(topicName).getDeclaredFields(); 

     for (Field a : fieldList) 
     { 
      if ((a.getType().getName().equals("int")) || (a.getType().getName().equals("long")) || (a.getType().getName().equals("short")) || (a.getType().getName().equals("byte")) 
        || (a.getType().getName().equals("boolean")) || (com.rti.dds.util.Enum.class.isAssignableFrom(a.getType()))) 
      { 
       query = query + "'" + a.getName() + "'" + " INTEGER,"; 
      } else if (a.getType().getName().equals("java.lang.String")) 
      { 
       query = query + "'" + a.getName() + "'" + " TEXT,"; 
      } else if (a.getType().getName().equals("float")) 
      { 
       query = query + "'" + a.getName() + "'" + " REAL,"; 
      } else if (a.getType().isArray() && ((a.getType().getName().startsWith("[")))) 
      { 
       if (a.getType().getName().equals("[F")) 
       { 
        for (int i = 0; i < Array.getLength(a.get(Class.forName(topicName))); i++) 
        { 
         query = query + "'" + a.getName() + "[" + i + "]' REAL,"; 
        } 
       } else if ((a.getType().getName().equals("[Ljava.lang.String;"))) 
       { 
        for (int i = 0; i < Array.getLength(a.get(Class.forName(topicName))); i++) 
        { 
         query = query + "'" + a.getName() + "[" + i + "]' TEXT,"; 
        } 
       } else if (a.getType().getName().equals("[I") || a.getType().getName().equals("[S") || a.getType().getName().equals("[B") 
         || (com.rti.dds.util.Enum.class.isAssignableFrom(Class.forName(a.getType().getName().replace(";", "").replace("[L", ""))))) 
       { 
        for (int i = 0; i < Array.getLength(a.get(Class.forName(topicName))); i++) 
        { 
         query = query + "'" + a.getName() + "[" + i + "]' INTEGER,"; 
        } 
       } else 
       { 
        // TODO: Arrays of objects not enums. 
       } 
      } else 
      { 
       processColumnData(a.getType().getName()); 
      } 

     } 
    } catch (SecurityException e) 
    { 
     // TODO Auto-generated catch block 
     System.out.println("Security Exception"); 
     return null; 
    } catch (ClassNotFoundException e) 
    { 
     // TODO Auto-generated catch block 
     System.out.println("Class not found " + topicName); 
     return null; 
    } catch (IllegalArgumentException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) 
    { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    System.out.println(query); 
    return query; 
} 

Les primitives sont droites au point, mais quand je reçois à des tableaux, il ne me laisse pas déterminer la taille. Je sais que je devrais passer dans une instance de la classe à get() au lieu de la classe elle-même mais je n'ai pas actuellement d'instance. Voici un exemple d'un objet avec un tableau qui peut entrer dans la fonction ci-dessus:

public class jOverLoad implements Copyable, Serializable{ 

public int machineId= 0; 
public int motorIndex= 0; 
public int motorDescriptionTidx= 0; 
public jTimeType timeOfLastThermalTrip = (jTimeType)jTimeType.create(); 
public float thermalTimer= 0; 
public boolean thermalWarning= false; 
public boolean thermalTrip= false; 
public boolean jamWarning= false; 
public boolean jamTrip= false; 
public int jamResetTimer= 0; 
public float phaseImbalance= 0; 
public boolean phaseImbalanceTrip= false; 
public boolean phaseAOK= false; 
public boolean phaseBOK= false; 
public boolean phaseCOK= false; 
public jRtdStatus [] rtdTripStatus= new jRtdStatus [(J_MAX_MOTOR_RTDS.VALUE)]; 

Je figurés puisque la taille est définie dans l'instanciation du tableau, je en quelque sorte être en mesure d'obtenir cette valeur. Y a-t-il un moyen?

+1

La longueur n'est pas une propriété des types de tableau. Seules les instances * array * ont des longueurs. –

+0

Je sais, mais comme il est instancié en haut de la classe tel qu'il est ... n'est-ce pas déjà une instance dans la classe? - PS Je suis en danger ici. – Tacitus86

+0

Mon humble conseil: sérialiser (comme json?) Et stocker comme texte dans votre DB –

Répondre

0

Alors ce que je faisais pour résoudre c'était de créer une instance faux de l'objet par:

Class.forName(topicName).getConstructor().newInstance() 

et j'y suis passé dans le a.get() pour trouver la longueur du tableau.

-2

Vous pouvez utiliser le isArray getter pour la classe de classe:

Integer[] array = { 1, 2, 3, 4, 5 }; 
    Object obj = array; 

    int lenght; 

    if(obj.getClass().isArray()){ 
     lenght = (Integer)obj.getClass().getField("lenght").get(obj); 
    } 
+0

C'est une instance d'un tableau. Je n'ai que l'objet de classe où je sais que l'un des champs est un tableau. – Tacitus86

+1

'NoSuchFieldException: lenght' --- Fixe même typ:' NoSuchFieldException: length' – Andreas