سؤال

كنت أكتب toString() لفئة في جاوة اليوم الآخر يدويا كتابة كل عنصر من فئة إلى سلسلة خطر لي أن استخدام التفكير قد يكون من الممكن إنشاء عامة toString() الطريقة التي يمكن أن تعمل على جميع الطبقات.I. E.ذلك أن معرفة أسماء الحقول والقيم وإرسالهم إلى سلسلة.

الحصول على أسماء الحقول هي بسيطة إلى حد ما, هنا هو ما زميل جاء مع:

public static List initFieldArray(String className) throws ClassNotFoundException {

    Class c = Class.forName(className);
    Field field[] = c.getFields();
    List<String> classFields = new ArrayList(field.length);

    for (int i = 0; i < field.length; i++) {
        String cf = field[i].toString();
        classFields.add(cf.substring(cf.lastIndexOf(".") + 1));
    }

    return classFields;
}

استخدام مصنع لا يمكن أن تقلل من أداء النفقات العامة عن طريق تخزين الحقول مرة, المرة الأولى toString() يسمى.ومع ذلك إيجاد قيم يمكن أن يكون هناك الكثير أكثر تكلفة.

بسبب الأداء من انعكاس هذا قد يكون أكثر افتراضية ثم العملي.ولكن أنا مهتم في فكرة انعكاس وكيف يمكنني استخدامه لتحسين لغتي البرمجة اليومية.

هل كانت مفيدة؟

المحلول

وأباتشي العموم لانغ <لأ href = "http://commons.apache.org/proper/commons-lang//apidocs/org/apache/commons/lang3/builder/ReflectionToStringBuilder.html" يختلط = "noreferrer" > ReflectionToStringBuilder يفعل ذلك بالنسبة لك.

import org.apache.commons.lang3.builder.ReflectionToStringBuilder

// your code goes here

public String toString() {
   return ReflectionToStringBuilder.toString(this);
}

نصائح أخرى

وثمة خيار آخر، إذا كنت طيب مع JSON، هو مكتبة GSON جوجل.

public String toString() {
    return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}

وانها تنوي القيام به انعكاس لك. وهذا ينتج لطيفة وسهلة لقراءة ملف JSON. سهلة القراءة إلى كونها النسبي غير اهل التكنولوجيا، قد تجد JSON تخويف.

هل يمكن جعل GSONBuilder متغير عضو أيضا، إذا كنت لا تريد أن الجديد هو فوق كل مرة.

إذا كان لديك البيانات التي لا يمكن أن تكون مطبوعة (مثل تيار) أو بيانات انك لا تريد طباعتها، يمكنك فقط إضافة علاماتExpose إلى السمات التي تريد طباعتها ومن ثم استخدام السطر التالي.

 new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation()
.create()
.toJson(this);

وW / التفكير، وأنا لم يكن على بينة من مكتبة اباتشي:

و(يكون على علم أنه إذا قمت بذلك سوف تحتاج على الأرجح للتعامل مع subobjects وتأكد من أنها الطباعة بشكل صحيح - على وجه الخصوص، والمصفوفات لا تظهر لك أي شيء مفيد)

@Override
public String toString()
{
    StringBuilder b = new StringBuilder("[");
    for (Field f : getClass().getFields())
    {
        if (!isStaticField(f))
        {
            try
            {
                b.append(f.getName() + "=" + f.get(this) + " ");
            } catch (IllegalAccessException e)
            {
                // pass, don't print
            }
        }
    }
    b.append(']');
    return b.toString();
}


private boolean isStaticField(Field f)
{
    return Modifier.isStatic(f.getModifiers());
}

إذا كنت تستخدم الكسوف، كما قد يكون لك نظرة على JUtils toString مولد ، التي يفعل ذلك بشكل ثابت (توليد الأسلوب في التعليمات البرمجية المصدر).

وليس التفكير، ولكن كان لي نظرة على توليد أسلوب ToString (جنبا إلى جنب مع الأنداد / شفرة التجزئة) كخطوة بعد تجميع باستخدام التلاعب بايت كود. كانت مختلطة نتائج.

يمكنك استخدام نفذت بالفعل المكتبات ، ReflectionToStringBuilder من أباتشي العموم لانغ.كما ذكر.

أو كتابة smt مماثلة من قبل نفسك انعكاس API.

هنا بعض الأمثلة:

class UniversalAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}

وهنا هو ما يعادل نتبيانس إلى الإجابة اوليفييه. الذكية codegen المساعد لنتبيانس .

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top