简体   繁体   English

获取Java中所有公共变量的名称和值(包括继承对象的名称和值)

[英]Get all public variables names & values (including of inherited object) in Java

  • edit - Here I gave a specific obj. 编辑-在这里我给了一个特定的对象。 as an example but I'm asking for any obj. 作为一个例子,但我要的是任何obj。 I am given * 我得到*

I'm looking for a way to get all public attributes in the class and all subclasses of an object (name of the attribute and its value). 我正在寻找一种方法来获取对象的类和所有子类中的所有公共属性(属性名称及其值)。 Let say we have a People object: 假设我们有一个People对象:

i

mport java.util.ArrayList;

    public class People {
        public ArrayList<Person> ppl= new ArrayList<Person>();
        int count=2;
        public People() {
            ppl.add(new Person(55, "Daddy", "Long Legs"));
            ppl.add(new Person(20, "Jhon", "Snow"));
        }
        public class Person{
            public int age;
            public Name name;
            public Person(int age, String first, String last){
                this.name = new Name(first, last);
                this.age = age;
            }
            public class Name{
                String first;
                String last;
                public Name(String first, String last) {
                    this.first = first;
                    this.last = last;
                }
            }
        }

    }

I saw a reference here (I can't comment on there bc I don't have enough points): Java reflection get sub class variable values / get object instance from member field 我在这里看到了一个参考(我不能在这里发表评论,因为我没有足够的分数): Java反射从成员字段获取子类变量值/获取对象实例

and tried to implement it also but then my output is 并尝试实现它,但是我的输出是

ppl [People$Person@4aa298b7, People$Person@7d4991ad]

whereas I need it needs to go into each Person and extract its variables(and their values). 而我需要它需要进入每个人并提取其变量(及其值)。 I searched for a information that could help me but I couldn't find anything..any advice? 我搜索了可以帮助我的信息,但找不到任何建议。

code a toString() method 编写toString()方法

What you are getting People$Person@4aa298b7 is the Object.toString representation.... 您得到的People$Person@4aa298b7Object.toString表示形式。

getClass().getName() + '@' + Integer.toHexString(hashCode())

IMHO You need to override the toString() method in both classes: Person and Name . 恕我直言,您需要在两个类PersonName重写toString()方法。

For example: 例如:

public class Name{
    String first;
    String last;
    public Name(String first, String last) {
        this.first = first;
        this.last = last;
    }

    @Override
    public String toString() {
        return this.first + " " + this.last;
    }
} 

get fields and values based on known Person class 根据已知的Person类获取字段和值

If this does not fit, you can get fields names and values using reflection like this: 如果不合适,则可以使用反射来获取字段名称和值,如下所示:

public static void main(String[] args) throws IllegalAccessException
{
    People pe = new People();
    Field[] allFields = People.Person.class.getDeclaredFields();

    for (Field field : allFields)
    {
      for (People.Person p : pe.ppl)
        System.out.println("Name: " + field.getName() + ". Value: " + field.get(p));
    }
}

OUTPUT: OUTPUT:

Name: age. Value: 55
Name: age. Value: 20
Name: name. Value: Daddy Long Legs
Name: name. Value: Jhon Snow
Name: this$0. Value: People@677327b6
Name: this$0. Value: People@677327b6

NOTE: if you don't want this 2 final values representing the People with ugly results you can: 注意:如果您不希望这2个最终值代表具有丑陋结果的People,则可以:

  • Split Person and Name and make them 2 independent classes 拆分“ Person和“ Name并使其成为两个独立的类
  • Make a toString() method in People class People类中创建toString()方法

dynamically get fields from inner classes 从内部类动态获取字段

If you want to dynamically get fields from inner classes: 如果要动态从内部类获取字段:

public static void main(String[] args) throws IllegalAccessException
{
    Class[] allClasses = People.class.getClasses();

    for (Class clazz : allClasses) {
      Field[] allFields = clazz.getFields();
      for (Field field : allFields) {
        String className = clazz.getName();
        String fieldName = field.getName();
        System.out.println("Class name: " + className + " - Field name: " + fieldName + ".");
      }
    }
}

OUTPUT: OUTPUT:

Class name: People$Name - Field name: first.
Class name: People$Name - Field name: last.
Class name: People$Person - Field name: age.
Class name: People$Person - Field name: name.

But not sure how you can get values from inside the ArrayList<Person> .... 但不确定如何从ArrayList<Person> ...中获取值。

public People() {
        ppl.add(new Person(55, "Daddy", "Long Legs"));
        ppl.add(new Person(20, "Jhon", "Snow"));

        for (Person person : ppl) {
            System.out.println(person.name.last);
            System.out.println(person.name.first);
            System.out.println(person.age);
        }

        System.out.println("Size of list: " + ppl.size());
    }

Example without toString() method. 没有toString()方法的示例。

I believe the closest you can get is related to this question java: get all variable names in a class . 我相信您可以得到的最接近与此Java问题有关:在一个类中获取所有变量名

Using Field[] fields = YourClassName.class.getFields(); 使用Field[] fields = YourClassName.class.getFields(); returns all class fields as java.lang.reflect.Field . java.lang.reflect.Field的形式返回所有类字段。

You can check if field is public using Field.getModifiers() and Modifier.isPublic(Modifier) . 您可以使用Field.getModifiers()Modifier.isPublic(Modifier)来检查字段是否公开。

You can get the field value using Object Field.get() . 您可以使用Object Field.get()获得字段值。

Hope that helps. 希望能有所帮助。

I Agree with @Jordi Castilla , you need to override toString method properly to get correct output. 我同意@Jordi Castilla,您需要正确重写toString方法以获得正确的输出。

For Example : 例如 :

import java.util.ArrayList;
class People {

    public ArrayList<Person> ppl= new ArrayList<Person>();
    int count=2;
    public People() {
        ppl.add(new Person(55, "Daddy", "Long Legs"));
        ppl.add(new Person(20, "Jhon", "Snow"));
    }

    @Override
    public String toString() {
        return "{ Count: "+this.count + " , People:" + this.ppl+" }";
    }

    public class Person{
        public int age;
        public Name name;
        public Person(int age, String first, String last){
            this.name = new Name(first, last);
            this.age = age;
        }


        @Override
        public String toString() {
            return "{ Name: "+this.name + " , Age:" + this.age+" }";
        }

        public class Name{
            String first;
            String last;
            public Name(String first, String last) {
                this.first = first;
                this.last = last;
            }

            @Override
            public String toString() {
                return "{ FirstName: "+this.first + ", LastName: " + this.last+ " }";
            }
        }
    }


  public static void main(String[] args) {
    People ppl = new People();
    System.out.println("OUTPUT => "+ ppl.toString());

  }
}


//Output

OUTPUT => { 
    Count: 2 , 
    People:[
        { Name: { FirstName: Daddy, LastName: Long Legs } , Age:55 }, 
        { Name: { FirstName: Jhon, LastName: Snow } , Age:20 }
    ] 
}

here is a recursive method I did (after I added a toString method to Name class). 这是我做的一个递归方法(在给Name类添加toString方法之后)。 Here it is. 这里是。 However, it is still doesn't prints the variable names inside the ppl list: 但是,它仍然不会在ppl列表中打印变量名称:

private static String getAllFields(Object obj){
    Class<?> objClass = obj.getClass();
    StringBuilder res = new StringBuilder();
    Field[] fields = objClass.getFields();
    res.append(objClass+"\n");

    for(Field field : fields) {
        Class<?> type = field.getType();
        String name = field.getName();
        res.append(" name: "+name+ " ");

        try {
            Object value = field.get(obj);
            res.append("value: "+value+ "\n");
            if (!type.isPrimitive() && !name.contains("java.lang"))
            {
                res.append(getAllFields(value));
            }
        } catch (IllegalArgumentException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    return res.toString();
}

here is the output: class People name: ppl value: [Daddy Long Legs 55 , Jhon Snow 20 ] class java.util.ArrayList name: count value: 2 这是输出: class People name: ppl value: [Daddy Long Legs 55 , Jhon Snow 20 ] class java.util.ArrayList name: count value: 2

notice that there isn't the Person class name there in the output or the names of the variable names of the variables there. 请注意,输出中没有Person类名称,也没有变量的名称。 I don't really understand why 我不太明白为什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM