1

I have an example class below and I want to return all class fields of certain type, in this example of type Image.

public class Contact {
    private String surname, lastname, address;
    private int age, floor;
    private Image contactPhoto, companyPhoto;
    private boolean isEmployed;

    public String[] getAllImages() {
        String images[] = // missing code
        return images;
        // in this case, I want to return {"contactPhoto","companyPhoto"}
    }
}

I need a help here. How can I find all class fields of certain type. I will be calling this method in another class ofc.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
ononononon
  • 1,033
  • 4
  • 14
  • 25

4 Answers4

6

Use reflection to access the fields declared on the class. Then iterate through the fields and check to see if their type matches Image.

You could also create a more useful method by accepting two parameters a target Class and a searchType Class. The method would then searches for fields with the target of the type searchType.

I would also recommend making this method static, since it really doesn't depend on any of the classes state.

Example

public class Contact {
    private String surname, lastname, address;
    private int age, floor;
    private Image contactPhoto, companyPhoto;
    private boolean isEmployed;

    public static String[] getFieldsOfType(Class<?> target, Class<?> searchType) {

        Field[] fields  = target.getDeclaredFields();

        List<String> results = new LinkedList<String>();
        for(Field f:fields){
            if(f.getType().equals(searchType)){
                results.add(f.getName());
            }
        }
        return results.toArray(new String[results.size()]);
    }

    public static String[] getAllImages(){
        return getFieldsOfType(Contact.class, Image.class); 
    }

    public static void main(String[] args) {
        String[] fieldNames = getAllImages();

        for(String name:fieldNames){
            System.out.println(name);
        }
    }
}
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Yes this should be it! I will try with this example – ononononon Dec 11 '14 at 22:29
  • @SotiriosDelimanolis Answer abstracted to better accommodate indecisiveness. :) – Kevin Bowersox Dec 11 '14 at 22:30
  • @MariánZekeŠedaj Glad I could help! I tried to modify the answer to make it a little more reusable. I would also advocate for making the method static, since you really don't need an instance of the class. – Kevin Bowersox Dec 11 '14 at 22:34
  • 1
    I really want to point out to OP that he could save himself all the trouble with reflection by simply putting the images in a List which can then be returned instead. It's much more elegant, faster, simpler to read and easier to expand. – runDOSrun Dec 11 '14 at 22:40
  • @runDOSrun We don't know the entire use case, maybe this is just for experimentation. I would also think a `Map` could work well. Use the `String` key to get the names. – Kevin Bowersox Dec 11 '14 at 22:42
  • 1
    @KevinBowersox Yes, Map would be ideal. True, we don't know. That's why it's good to make sure OP doesn't think this approach is the "standard way". – runDOSrun Dec 11 '14 at 22:48
2

A simpler alternative to using reflection would be to use a map as the primary data type for the field you are interested in:

public class Contact {

    private static final String CONTACT_PHOTO = "contactPhoto";
    private static final String COMPANY_PHOTO = "companyPhoto";

    private String surname, lastname, address;
    private int age, floor;
    private HashMap<String, Image> images;
    private boolean isEmployed;

    public Contact() {
        images = new HashMap<String, Image>();
        images.put(CONTACT_PHOTO, null);
        images.put(COMPANY_PHOTO, null);
    }

    public String[] getAllImages() {
        Set<String> imageNames = images.keySet();
        return imageNames.toArray(new String[imageNames.size()]);
    }

    public void setContactPhoto(Image img) {
        images.put(CONTACT_PHOTO, img);
    }

    public Image getContactPhoto() {
        return images.get(CONTACT_PHOTO);
    }

    public void setCompanyPhoto(Image img) {
        images.put(COMPANY_PHOTO, img);
    }

    public Image getCompanyPhoto() {
        return images.get(COMPANY_PHOTO);
    }
}
Marc Ransome
  • 121
  • 3
1

Using field names as values can cause headaches.

If you need to identify individual images with strings, you could create a HashMap. Use your current field names as keys and Image objects as values.

https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html

You can retrieve all key values (in your case,the names) via the method keySet()

Edit: Here's a working example class, derived from yours, but only with the relevant fields:

import java.awt.Image;
import java.util.HashMap;
import java.util.Set;

public class Contact
{
    private HashMap<String, Image> images;

    public Contact ()
    {
        images = new HashMap<String, Image>();
        images.put( "contactPhoto", null);
        images.put( "companyPhoto", null);
    }

    public Set<String> getAllImages()
    {
        return images.keySet();
    }

    public static void main(String[] args)
    {
        System.out.println(new Contact().getAllImages());
    }
}
null
  • 5,207
  • 1
  • 19
  • 35
0

use:

Field[] fields=this.getClass().getFields();
...
 for (...){
  if ( fields[i].getType() == ?? ){
  ...
  }
 }
diegoyucra
  • 24
  • 2