Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NoSuchFieldException when field exists

I'm getting a java.lang.NoSuchFieldException when trying to run the following method:

 public void getTimes(String specialty, String day) {
    ArrayList<Tutor> withSpec = new ArrayList<Tutor>();
    for (Tutor t : tutorList){
        try {
            Time startTime = (Time)t.getClass().getField(day + "Start").get(t);
        } catch (NoSuchFieldException | SecurityException | IllegalAccessException ex) Logger.getLogger(DBHandler.class.getName()).log(Level.SEVERE, null, ex); }

The error is on the line Time startTime = (Time)t.getClass().getField(day + "Start").get(t);

I don't understand this error, because monStart is a field of the Tutor class:

Public class Tutor implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "tutorID")
private Integer tutorID;

.... 

@Column(name = "monStart")
@Temporal(TemporalType.TIME)
 Date monStart;

I'm just learning to use reflection, so I'm sure this is some sort of a syntactical error...

like image 873
drew moore Avatar asked Mar 14 '13 21:03

drew moore


People also ask

What is NoSuchFieldException?

Class NoSuchFieldExceptionSignals that the class doesn't have a field of a specified name.

What is getDeclaredField?

getDeclaredFields() method returns an array of Field objects including public, protected, default (package) access, and private fields, but excludes inherited fields.


5 Answers

The getField method will only find the field if it's public. You will need to use the getDeclaredField method instead, which will find any field that is declared directly on the class, even if it's not public.

like image 68
rgettman Avatar answered Nov 15 '22 03:11

rgettman


According to the javadoc, Class.getField() "Returns a Field object that reflects the specified public member field of the class or interface represented by this Class object". Use getDeclaredField() if you want to access non-public fields.

like image 32
Costi Ciudatu Avatar answered Nov 15 '22 01:11

Costi Ciudatu


Best solutions for getClass().getField() problem are:

  1. Use getDeclaredField() instead of getField():
        String propertyName = "test";
        Class.forName(this.getClass().getName()).getDeclaredField(propertyName);
  1. Replace "HelloWorld" with your class name:
        String propertyName = "name";
        HelloWorld.class.getDeclaredField(propertyName);

If you want to get the annotation length of the column:

HelloWorld.class.getDeclaredField(propertyName).getAnnotation(Column.class).length();
like image 8
Murali Krishna Valluri Avatar answered Nov 15 '22 03:11

Murali Krishna Valluri


For any Android developers seeing this that still can't seem to fix the issue, check to see if Proguard is enabled. If it is, it's possible the class in question is being obfuscated and you'll need to add rules to prevent that from happening.

like image 6
Brian Yencho Avatar answered Nov 15 '22 01:11

Brian Yencho


As mentioned in the accepted answer, using getDeclaredField will potentially solve your problem (in case the field wasn't declared as public).

If you are still getting the NoSuchFieldException, then it might be because that field is actually in the superclass! Indeed, if your class extends another class, then you will not get the inherited fields through the getDeclaredField method. Here is how to fix that problem:

String propertyName = "foo";
yourClass.getClass().getSuperClass().getDeclaredField(propertyName);
like image 3
payne Avatar answered Nov 15 '22 03:11

payne