Вот как это сделать, используя dom4j :
Импорт:
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
Код:
String xml = " ";
Document doc = DocumentHelper.parseText(xml);
StringWriter sw = new StringWriter();
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xw = new XMLWriter(sw, format);
xw.write(doc);
String result = sw.toString();
Просто потому, что List#toArray()
возвращает Object[]
, поэтому нет никакой гарантии от этого метода, что он вернет T[]
Теперь на практике это нормально, так как вы всегда знаете, что он вернет требуемый тип
Вы можете использовать @SuppressWarnings("unchecked")
, чтобы избежать появления этого предупреждения
Во-первых, обратите внимание, что массивы знают свой тип компонента во время выполнения, но экземпляры универсальных классов не знают аргумента универсального типа во время выполнения. List<T>
не может создать объект массива во время выполнения с типом времени выполнения T[]
без дополнительной информации, поскольку он не знает, что такое T
во время выполнения. Метод List#toArray()
, который принимает один параметр массива, использует тип времени выполнения переданного экземпляра массива для создания массива того же типа компонента во время выполнения. Но List#toArray()
без параметров всегда создает массив с типом времени выполнения Object[]
. Таким образом, elements.toArray()
оценивает экземпляр массива, который всегда имеет тип времени выполнения Object[]
.
Object[]
не является подтипом T[]
(когда T
не является Object
), поэтому присвоение этого массива this.elements
типа времени компиляции T[]
является неправильным. Однако это не вызывает немедленных исключений, поскольку стирание T
равно Object
, поэтому стирание T[]
равно Object[]
, и присвоение Object[]
Object[]
хорошо. Это не вызовет никаких проблем, если вы никогда не будете выставлять объект, содержащийся в this.elements
, снаружи этого объекта как T[]
. Однако, если вы выставите объект, содержащийся в this.elements
как тип T[]
, вне класса (например, метод, который возвращает this.elements
как тип T[]
, или если вы сделаете this.elements
открытым или защищенным полем), вызывающая сторона вне класса может ожидать, что T
будет определенного типа, и это может вызвать исключение приведения класса.
Например, если у вас есть метод, который возвращает this.elements
типа T[]
:
public T[] getElements() {
return this.elements;
}
, а затем у вас есть вызывающая сторона, которая содержит ArrayTypeErasure<String>
и она вызывает .getElements()
для него , это будет ожидать String[]
. Когда он пытается присвоить результат String[]
, он вызовет исключение приведения класса, так как тип времени выполнения объекта - Object[]
:
ArrayTypeErasure<String> foo = ...
String[] bar = foo.getElements();
Из-за стирания типа вы можете разыграть List<X>
с List<Y>
с.
ArrayTypeErasure<String> er = new ArrayTypeErasure<>();
ArrayTypeErasure erased = er;
List intList = new List<Integer>(); // compile warnings, but
intList.add(1);
erased.setElements(intList);