2010-06-30 16 views
9

La situación parece anormal, pero se me pidió que creara el serializador que analizará un objeto en cadena concatenando los resultados de los métodos "get". Los valores deben aparecer en el mismo orden en que se declara su equivalente "get" en el archivo de código fuente.Obtenga los métodos declarados para que aparezcan en el código fuente

Así, por ejemplo, tenemos

Class testBean1{ 
    public String getValue1(){ 
    return "value1"; 
    } 

    public String getValue2(){ 
    return "value2"; 
    } 
} 

El resultado debería ser:

"value1 - value2" 

An no

"value2 - value1" 

No se puede hacer con objeto de acuerdo con Class la documentación. Pero me pregunto si puedo encontrar esta información en el archivo "* .class" o ¿está perdido? Si tal información existe, tal vez, ¿alguien conoce una herramienta lista para usar para ese propósito? Si no se puede encontrar dicha información, sugiérale la forma más profesional de lograr el objetivo. Pensé en agregar algún tipo de anotaciones personalizadas a los usuarios de la clase que deberían ser serializados.

+0

¿Quién preguntó esto? –

+0

=) Decidimos usar anotaciones. ¡Todo esta bien! – Denis

+1

En caso de que esté interesado, respondí una pregunta muy similar para otra persona, en realidad es bastante fácil (lea también los comentarios): http://stackoverflow.com/questions/12834887/how-to-get-the- line-number-of-a-method/14973713 # comment21272750_14973713 – Quaternion

Respuesta

1

No creo que la información se conserve.

JAXB, por ejemplo, tiene @XmlType(propOrder="field1, field2") donde define el orden de los campos cuando se serializan a xml. Puede implemenet algo similar

+2

En realidad, esta información se conserva la mayor parte del tiempo (valor predeterminado de Eclipse y Sun javac para permitir líneas en los rastros de la pila). Si es así, uno podría analizar LineNumberTables del archivo de clase en cuestión y deducir el orden de los métodos. Por supuesto, esto no es muy elegante. Creo que tu sugerencia es mucho mejor. – musiKk

+0

sí, incluso si la información se retiene, dudo que sea confiable – Bozho

+0

Pensé en algo así (anotaciones). Solo quería asegurarme de que el orden de los métodos no se puede lograr directamente desde bytecode. "muzikk" tu oferta parece ser muy útil. Usaré información de depuración si no llegamos a un acuerdo sobre el uso de anotaciones. ¿Sabe en qué documento se reclama el mantenimiento del orden de los métodos? – Denis

0

Escriba su anotación personalizada para almacenar los datos de pedido, a continuación, utilizar Method.getAnnotation (Clase annotationClass)

3

Si quieres que tiene que analizar el código fuente, no el código de bytes.

Hay una serie de bibliotecas que analizan un archivo fuente en un árbol de nodos, mi favorito es el javaparser (alojado en code.google.com), que, en una versión ligeramente modificada, también es utilizado por Spring Roo.

En the usage page puede encontrar algunas muestras. Básicamente, querrá usar un Visitante que escuche las Definiciones de Método.

+1

Google no tiene nada que ver con ese analizador de Java. –

+0

tienes razón, por supuesto. Actualicé mi respuesta –

+0

gracias por la sugerencia! Pero solo las clases compiladas están disponibles. – Denis

0

Editar: Esto funciona solo en clases concretas (la clase para inspeccionar tiene su propio archivo .class). Cambié el código a continuación para reflejar esto. Hasta que se profundice en la biblioteca ClassFileAnalyzer para trabajar directamente con las clases en lugar de leerlas desde un archivo temporal, esta limitación existe.

Siguiendo enfoque funciona para mí:

Descargar y la importación tras libarary ClassFileAnalyzer

Añadir los dos métodos estáticos siguientes (Atención getClussDump() necesita una pequeña modificación para escribir el archivo de clase a un temporal! archivo: me quité el código aquí porque es muy especial en este punto):

public static String getClassDump(Class<?> c) throws Exception { 
    String classFileName = c.getSimpleName() + ".class"; 
    URL resource = c.getResource(classFileName); 
    if (resource == null) { 
     throw new RuntimeException("Works only for concreate classes!"); 
    } 
    String absolutePath = ...; // write to temp file and get absolute path 
    ClassFile classFile = new ClassFile(absolutePath); 
    classFile.parse(); 
    Info infos = new Info(classFile, absolutePath); 
    StringBuffer infoBuffer = infos.getInfos(); 
    return infoBuffer.toString(); 
} 

public static <S extends List<Method>> S sortMethodsBySourceOrder(Class<?> c, S methods) throws Exception { 
    String classDump = getClassDump(c); 
    int index = classDump.indexOf("constant_pool_count:"); 
    final String dump = classDump.substring(index); 
    Collections.sort(methods, new Comparator<Method>() { 
    public int compare(Method o1, Method o2) { 
     Integer i1 = Integer.valueOf(dump.indexOf(" " + o1.getName() + lineSeparator)); 
     Integer i2 = Integer.valueOf(dump.indexOf(" " + o2.getName() + lineSeparator)); 
     return i1.compareTo(i2); 
    }}); 
    return methods; 
} 

Ahora usted puede llamar a la sortMethodsBySourceOrder con cualquier lista de métodos (becau la ordenación de matrices no es muy cómoda) y se volverá a ordenar la lista.

Funciona observando el conjunto constante de vuelcos de clase que a su vez puede ser determinado por la biblioteca.

Greetz, ghad

+0

¡Gracias! Aunque decidimos usar anotaciones, seguramente probaré tu código más adelante. – Denis

1

Aunque reflexión no hace más (a partir de Java 7 creo) le dará los métodos en el orden en que aparecen en el código fuente, el archivo de clase parece todavía (a partir de Java 8) contienen los métodos en el orden en que aparecen en el código fuente.

Por lo tanto, puede analizar el archivo de clase buscando nombres de métodos y luego ordenar los métodos según el desplazamiento del archivo en el que se encontró cada método.

Si quieres hacerlo de una forma menos hacky puedes utilizar Javassist, que te dará el número de línea de cada método declarado, para que puedas ordenar los métodos por número de línea.

Cuestiones relacionadas