指向摘要 class

Pointing to Abstract class

我对抽象有一定的了解class。它不能自己实例化,但可以由 class 实现它的人或匿名的 classes 实例化。我希望它是正确的..!

但是我遇到了下面的代码。

SAXParserFactory factory = SAXParserFactory.newInstance(); 

这是一个 newInstance 源代码:

public static SAXParserFactory newInstance()
  86:     throws FactoryConfigurationError
  87:   {
  88:     ClassLoader loader = Thread.currentThread().getContextClassLoader();
  89:     if (loader == null)
  90:       {
  91:         loader = SAXParserFactory.class.getClassLoader();
  92:       }
  93:     String className = null;
  94:     int count = 0;
  95:     do
  96:       {
  97:         className = getFactoryClassName(loader, count++);
  98:         if (className != null)
  99:           {
 100:             try
 101:               {
 102:                 Class t = (loader != null) ? loader.loadClass(className) :
 103:                   Class.forName(className);
 104:                 return (SAXParserFactory) t.newInstance();
 105:               }
 106:             catch (ClassNotFoundException e)
 107:               {
 108:                 className = null;
 109:               }
 110:             catch (Exception e)
 111:               {
 112:                 throw new FactoryConfigurationError(e,
 113:                      "error instantiating class " + className);
 114:               }
 115:           }
 116:       }
 117:     while (className == null && count < 3);
 118:     return new gnu.xml.stream.SAXParserFactory();
 119:   }
 120: 
 121:   private static String getFactoryClassName(ClassLoader loader, int attempt)
 122:   {
 123:     final String propertyName = "javax.xml.parsers.SAXParserFactory";
 124:     switch (attempt)
 125:       {
 126:         case 0:
 127:           return System.getProperty(propertyName);
 128:         case 1:
 129:           try
 130:             {
 131:               File file = new File(System.getProperty("java.home"));
 132:               file = new File(file, "lib");
 133:               file = new File(file, "jaxp.properties");
 134:               InputStream in = new FileInputStream(file);
 135:               Properties props = new Properties();
 136:               props.load(in);
 137:               in.close();
 138:               return props.getProperty(propertyName);
 139:             }
 140:           catch (IOException e)
 141:             {
 142:               return null;
 143:             }
 144:         case 2:
 145:           try
 146:             {
 147:               String serviceKey = "/META-INF/services/" + propertyName;
 148:               InputStream in = (loader != null) ?
 149:                  loader.getResourceAsStream(serviceKey) :
 150:                 SAXParserFactory.class.getResourceAsStream(serviceKey);
 151:               if (in != null)
 152:                 {
 153:                   BufferedReader r =
 154:                      new BufferedReader(new InputStreamReader(in));
 155:                   String ret = r.readLine();
 156:                   r.close();
 157:                   return ret;
 158:                 }
 159:             }
 160:           catch (IOException e)
 161:             {
 162:             }
 163:           return null;
 164:         default:
 165:           return null;
 166:       }
 167:   }
 168: 

如果您看到代码,有可能返回 Reference type of SAXParserFactory is at line number 104 and 118.

在第 104 行,它正在创建动态 class。我想知道如何将新创建的 class 转换为抽象 class 类型 SAXParserFactory ?我在这里很困惑..!

并且在实例化 SAXParserFactory 之后,下面的代码 运行s

SAXParser saxParser = factory.newSAXParser();

所以一旦 SAXParserFactory 被实例化,抽象 class SAXParserFactory class 的 newSAXParser() 方法应该在使用它之前实现,但是从哪里调用它?因为实现SAXParserFactory class的class是在运行时创建的class!

97: className = getFactoryClassName(loader, count++);

这一行 returns extends class SAXParserFactory.
的全名 一个例子可能是

oracle.xml.jaxp.JXSAXParserFactory

然后

102: Class t = (loader != null) ? loader.loadClass(className)
103:                            : Class.forName(className);

Classloader 询问 JXSAXParserFactory Class 对象 (Class<JXSAXParserFactory>)。

104: return (SAXParserFactory) t.newInstance();

Class#newInstance 被调用,在这种情况下意味着 JXSAXParserFactory 的无参数构造函数被调用。

作为JXSAXParserFactory extends SAXParserFactory,可以向上转换。 这是正确的术语。

继承即继承父亲签名。显然,通过向上转换,您会丢失子 class.

的额外公开成员

SAXParserFactory#newSAXParser 将始终限于返回 SAXParser,但底层实现(基本上,逻辑)会有所不同。

https://en.wikipedia.org/wiki/Polymorphism_(computer_science)