2011-09-06 15 views
16

tengo una clase con diversas variablesver si existe campo en la clase

public class myClass{ 

    public int id; 
    public String category; 
    public String description; 
    public String start; 
    public String end; 
} 

¿Hay una manera de comprobar, ya sea mediante la creación de una función interna o la comprobación del objeto que llama, si existe o no una variable?

E.g. Para verificar si myClass contiene una variable llamada "categoría" (lo hace). O si contiene una categoría llamada "foo" (no lo hace).

Respuesta

29

su compilador sabe que por lo general bastante bien, y el tiempo de ejecución le permite examinar las clases cargadas con la reflexión.

Object someObject = ... 
Class<?> someClass = someObject.getClass(); 
Field someField = someClass.getField("foo"); 

El método getField() lanzará una excepción si el campo no se puede encontrar.

+3

O una SecurityException si no se puede acceder (por ejemplo, 'private') – CrackerJack9

+0

Perfecto, ¡gracias! – emachine

+2

@ CrackerJack9 no, el acceso a campos privados con 'getField()' no arroja 'SecurityException'. – Bombe

2

Puede hacerlo usando reflection, aunque le recomendaría comprobar si realmente se necesita o tal vez hay otra forma de hacerlo.

Por ejemplo:

Class<?> clz = MyClass.class; 
try { 
    Field f = clz.getField("foo") 
} 
catch (NoSuchFieldException ex) { 
    // field doesn't exist 
} 
catch (SecurityException ex) { 
    // no access to field 
} 
4

Como otros ya mencionados reflexión es lo que necesita.

Si necesita acceder a un campo privado puede utilizar Class.getDeclaredField(String name)

0

Utilice los siguientes métodos que utilizan Reflections-

private Set<String> getAllFields(final Class<?> type) { 
     Set<String> fields = new HashSet<String>(); 
     for (Field field : type.getDeclaredFields()) { 
      fields.add(field.getName()); 
     } 

     if (type.getSuperclass() != null) { 
      fields.addAll(getAllFields(type.getSuperclass())); 
     } 
     return fields; 
    }  
    private boolean listHasProperty(final Set<String> properties, final String propertyName) { 
     if (properties.contains(propertyName)) { 
      return true; 
     } 
     return false; 
    } 

continuación, compruebe si la propiedad está presente using-

Set<String> fieldSet = getAllFields(object.getClass()); 
boolean isPresent=listHasProperty(fieldSet , sourceProperty) 

Para obtener más detalles, consulte este post

0

Esto es un poco incómodo de hacer en un solo paso.

Cuando nos mudamos a concepto de polimorfismo existen desafíos como la generación carece de objetos para una clase (clase ABC) la toma de datos de forma dinámica haciendo referencia a otras clases dedicadas (ABCXMLDOMnodes clase, clase ABCHTMLDOMnodes) que contiene mismos campos, pero de tipo estático y definitivo. Espero que tengas el requerimiento.

1.Creating ArrayList of fields Nombres simples de estas tres clases como globales.

private static ArrayList<String> getAllFieldsSimpleNames(Class<?> beanClass) { 
    ArrayList<String> fieldNames = new ArrayList<String>(); 
    Field[] fields = beanClass.getDeclaredFields(); 
    for (Field field : fields) { 
     fieldNames.add(field.getName()); 
    } 
    return fieldNames; 
} 

2.And entonces cada vez de generar un objeto estamos validando campos (por ejemplo> 10 campos) en contra de las clases de ayuda, como a continuación es fácil que siento.

for(String a :abcFieldNames){ 
     if(abcXMLfieldnames.contains(a)){ 
     //code here 
     }else if(abcHTMLfieldnames.contains(a){ 
     //code here 
     } 
    } 

Otra forma más simple y dinámica es la creación de

 HashMap<Class<?>, ArrayList<String>> = ... 
    hm.put(ABC.class, getAllFieldsSimpleNames(ABC.class)); 
    hm.put(ABCXMLDOMnodes.class, getAllFieldsSimpleNames(ABCXMLDOMnodes.class)); 
if(hm.get(ABCXMLDOMnodes.class).contains("a"){...} 

Mi sugerencia a Oracle Corp.La red JAVA es si la "Clase de clase" puede proporcionar un método que devuelva una lista de nombres de campo de una clase determinada, ya que el tipo de cadena solo será útil.

12

Advertencia: la respuesta aceptada va a funcionar, pero se basa en excepciones como el flujo de control, que es bad practice y debe evitarse siempre que sea posible.

su lugar, considere la siguiente alternativa:

public boolean doesObjectContainField(Object object, String fieldName) { 
    Class<?> objectClass = object.getClass(); 
    for (Field field : objectClass.getFields()) { 
     if (field.getName().equals(fieldName)) { 
      return true; 
     } 
    } 
    return false; 
} 

o una forma más sucinta el uso de Java 8 corrientes:

public boolean doesObjectContainField(Object object, String fieldName) { 
    return Arrays.stream(object.getClass().getFields()) 
      .anyMatch(f -> f.getName().equals(fieldName)); 
} 

Estos fragmentos de código no se basan en excepciones como el flujo de control y de hecho lo hacen no requiere ningún manejo de excepción, lo que hará que su implementación sea más simple y más legible. Usted acaba de llamar a uno de los métodos anteriores con un trozo de código similar al siguiente:

Object someObject = ... ; 
boolean fieldExists = doesObjectContainField(someObject, "foo"); 

Como nota al margen, si necesita acceder a los campos privados de su clase (pero la clase no padres campos), puede simplemente reemplazar la llamada al getFields por getDeclaredFields.

Cuestiones relacionadas