5

最近,我一直在使用 XML 解析器。这对我来说才刚刚开始,我设法理解了如何在 java ie 中使用 DOM 解析器类DocumentBuilderFactoryDocumentBuilder解析 XML 文档。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();  
DocumentBuilder db = dbf.newDocumentBuilder();            

我要问自己的是,如何允许抽象类(例如DocumentBuilderFactoryand DocumentBuilder)实例化新实例?然后在另一个例子中我看到:

Calendar calendar = Calendar.getInstance();  
System.out.println(calendar.get(Calendar.DATE)); 
  1. 据我所知,您不能为抽象类和接口类实例化(换句话说,创建一个对象)。我对么?
  2. getInstance()和方法是否newInstancce()创建上述抽象类的实例?

我是否错过了使用抽象类及其新对象的一些东西?

4

4 回答 4

9

该方法是一个抽象工厂方法,它返回一个子类DocumentBuilder它是一个(具体)实现。

对象的确切类并不重要,您只需要知道它是一个DocumentBuilder. 该方法可以返回一个在运行时决定的实例,或者它认为合适的预定实例。

如果您想知道,可以像这样打印出实际的类:

 System.out.println(dbf.getClass());

注意,方法newInstance()不要与 的同名方法混淆Class,即两者是不同的:

 // a static method of this class
 DocumentBuilderFactory.newInstance(); 

// an instance method of Class
 DocumentBuilderFactory.class.newInstance();

一个不幸的名字选择肯定会引起混乱。

于 2013-05-11T07:07:24.007 回答
3

那是一个静态抽象工厂方法,它会返回一个子类型,DocumentBuilderFactory而不是它自己的实际实例。DocumentBuilderFactory它不像我想象的那样,你明白:

DocumentBuilderFactory dbf = new DocumentBuilderFactory();

DocumentBuilderFactory#newInstance() ,获取一个 DocumentBuilderFactory 的新实例。这个静态方法创建一个新的工厂实例。此方法使用以下有序查找过程来确定要加载的 DocumentBuilderFactory 实现类。

newInstance()将返回 的实现类(子类型)的实例,该实例DocumentBuilderFactory不是抽象的,并将对该对象的引用分配给 DocumentBuilderFactory引用变量。

于 2013-05-11T07:08:21.530 回答
1

这是一种静态方法。您可以在不引用实例的情况下调用抽象类(或任何类)的静态方法。

于 2013-05-11T07:09:47.280 回答
1

谢谢大家,在尝试了下面的代码后,我的疑问得到了解决。

日历 cls = Calendar.getInstance();
日期 dt = new Date();
System.out.println(cls.getClass()); //<------ 1
DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance(); System.out.println(dbls.getClass()); //<------2
DocumentBuilder db = dbls.newDocumentBuilder();
System.out.println(db.getClass()); //<--------3

我看到以下输出:

 ********Output******
   class java.util.GregorianCalendar
   class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl
   class com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl

a) 静态方法“DocumentBuilderFactory.newInstance()”返回名为“DocumentBuilderFactoryImpl”的子类型类实例。

b)“DocumentBuilderFactoryImpl”是抽象“DocumentBuilderFacotory”类的子类,因此如果我给出没有问题:

DocumentBuilderFacotryImpl dbls = DocumentBuilderFactory.newInstance();
//-----而不是给 DocumentBuilderFactory dbls = DocumentBuilderFactory.newInstance();

同样适用于 DocumentBuilderImpl db = dbls.newDocumentBuilder();
//---- 而不是 DocumentBuilder db = dbls.bewDocumentBuilder();

结论:newInstance()、newDocumentBuilder()、getInstance() 返回子类对象。虽然抽象类不能创建新的 Object ,但我们可以将子类对象分配给抽象类(即父)引用变量。前任:

抽象类 A{ }
类 B 扩展 A{ }

我们可以说:

 A a = new B();   

但不是

 A a = new A();
于 2013-05-12T12:05:52.750 回答