2016-06-01 3 views
0

У меня есть несколько классов pojo, используя код ниже.Общий класс для реализации ToString

public class ToStringImpl { 

public String toString(){ 
     StringBuilder result = new StringBuilder(); 
     String newLine = "\n"; 


     result.append(this.getClass().getName()); 
     result.append(" Data {"); 
     result.append(newLine); 

     //determine fields declared in this class only (no fields of superclass) 
     Field[] fields = this.getClass().getDeclaredFields(); 

     //print field names paired with their values 
     for (Field field : fields ) { 
     result.append(" "); 
     try { 
      result.append(field.getName()); 
      result.append(": "); 
      //requires access to private field: 
      result.append(field.get(this)); 
     } catch (IllegalAccessException ex) { 
      System.out.println(ex); 
     } 
     result.append(newLine); 
     } 
     result.append("}"); 

     return result.toString(); 
} 

} 

Как я могу назвать класс класса из разных классов? Предположим, у меня есть классы POJO называемые клиент, магазин, инвентарь

public class Customer { 

private String name; 
private String address; 

...getter...setter... 

public String toString(){ 

    ToStringImpl log = new ToStringImpl(); 
    //how do I pass different classes here? 
    return log.toString(); 
} 

} 

public class Store { 

private String logo; 
private String type; 

....getter...setter... 
} 

public class Inventory { 

private boolean isAvailable; 
private long index; 

...getter...setter 
} 

для каждого класса, как я пройти другой класс? или если есть лучший способ сделать это? или было бы лучше создать toString как интерфейс и реализовать его в каждом классе и передать его как конструктор?

+0

Если вы действительно хотите, чтобы метод принадлежал объектам (по сравнению с методом 'static', где-то где-то), попробуйте изучить [методы по умолчанию] (https://docs.oracle.com/javase/tutorial/java/IandI/defaultmethods.html) на интерфейсах – Michael

ответ

3

Что вы можете сделать, это метод toString() в ToStringImpl класс статический. Я бы не назвал это toString(), хотя, изменить его на что-то вроде getClassString()

Пример:

public static String getClassString(Object o) 
{ 
    StringBuilder result = new StringBuilder(); 
    String newLine = "\n"; 

    result.append(o.getClass().getName()); 
    result.append(" Data {"); 
    result.append(newLine); 

    // determine fields declared in this class only (no fields of 
    // superclass) 
    Field[] fields = o.getClass().getDeclaredFields(); 

    // print field names paired with their values 
    for (Field field : fields) 
    { 
     result.append(" "); 
     try 
     { 
      result.append(field.getName()); 
      result.append(": "); 
      // requires access to private field: 
      result.append(field.get(o)); 
     } 
     catch (IllegalAccessException ex) 
     { 
      System.out.println(ex); 
     } 
     result.append(newLine); 
    } 
    result.append("}"); 

    return result.toString(); 
} 

Тогда в классах POJO, вызовите его:

public String toString() 
{ 
    // how do I pass different classes here? 
    // by passing the 'this' reference 
    return ToStringImpl.getClassString(this); 
} 
+0

Спасибо! что уменьшило мне много дублированного кода. путем перезаписи toString – logger

0

Когда вы переопределяете метод, например Object#toString(), вы переопределяете его только для этого класса. Вы можете выполнить одно из следующих действий:

  • Добавьте ваш toString() к каждому классу, который может понадобиться, а затем просто позвонить toString() на этот объект от везде, где это. (не рекомендуется)
  • Расширьте свой ToStringImpl на каждом классе, который вы хотите, и вызовите toString() на объекте.
  • Сделать ToStringImpl#toString() статические и передать объект в качестве аргумента (рекомендуется), например:

    public static void objectToString(Object ob){ 
        //your code here, just replace "this" with "ob" 
    } 
    
1

Существует уже библиотека, которая делает это. Посмотрите ToStringBuilder в библиотеке Apache-общих, метод ToString ваших доменных объектов будет выглядеть следующим образом:

@Override public String toString() { 
    return ToStringBuilder.reflectionToString(this); 
} 

Лучший план бы, мне кажется, что вырвать доморощенные кода и падение в апача-достоянию, или используйте Project Lombok. Если вы должны изобрести это колесо, то копирование примера ToStringBuilder использования статического метода и выбор объекта для печати в качестве параметра было бы разумным.

ToStringBuilder включает функцию, позволяющую вам ограничивать, какие поля печататься, ваш собственный код должен делать что-то подобное ради вашего собственного здравомыслия. Метод toString используется для печати информации для отладки и ведения журнала. Если вы просто получите все поля, такие как ваш опубликованный код, он будет выгружать содержимое всего объекта каждый раз, когда вы вызываете toString в записи журнала, и у вас будет что-то нечитаемое, оно заполнит ваши журналы и замедлит ваше приложение, написав все это Информация.

Вы являетесь потребителем информации здесь, делайте это чем-то полезным, а не подавляющим.

+0

Чтобы подчеркнуть точку Натана: автоматическое включение каждого поля в значение toString является плохой практикой и его следует избегать. Недавно я работал над проектом, который сделал это, и классы с массивами и/или свойствами коллекции были катастрофой для печати. Единственное, что занесло в журнал, заставило приложение встать на колени. – VGR

Смежные вопросы