Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 指向抽象类_Java_Abstract Class - Fatal编程技术网

Java 指向抽象类

Java 指向抽象类,java,abstract-class,Java,Abstract Class,我有抽象类的基本知识。它不能被自己实例化,而是由实现它的类或匿名类实例化。我希望它是对的 但我遇到了下面的代码 SAXParserFactory factory = SAXParserFactory.newInstance(); 这里有一个newInstancesourc代码: public static SAXParserFactory newInstance() 86: throws FactoryConfigurationError 87: { 88:

我有抽象类的基本知识。它不能被自己实例化,而是由实现它的类或匿名类实例化。我希望它是对的

但我遇到了下面的代码

SAXParserFactory factory = SAXParserFactory.newInstance(); 
这里有一个
newInstance
sourc代码:

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: 
因此,一旦实例化了
SAXParserFactory
,就应该在使用它之前实现抽象类
SAXParserFactory
类的newSAXParser()方法,但是从何处调用它呢?因为实现
SAXParserFactory
类的类是在运行时创建的类

97: className = getFactoryClassName(loader, count++);
此行返回扩展了
SAXParserFactory
的类的全名
一个例子可能是

oracle.xml.jaxp.JXSAXParserFactory
然后

向类加载器请求
JXSAXParserFactory
Class
对象(
Class

调用了
Class#newInstance
,这意味着调用了
JXSAXParserFactory
的无参数构造函数

作为
JXSAXParserFactory扩展的SAXParserFactory
,它可以升级。 这是正确的术语

扩展意味着继承父亲的签名。显然,通过向上投射,您会丢失子类的其他暴露成员


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


这是反射和类加载的复杂混合体,您对这两者都有经验吗?任何实例都可以强制转换到它的一个超类或它实现的任何接口(例如,您可以将
Integer
的任何实例强制转换为
Number
Object
t
表示的类必须是
SAXParserFactory
第104行的子类:
t
是实现(子类)
SAXParserFactory
的类的类对象,因此,实际的类不是抽象的,可以毫无问题地进行转换。这真的是向上转换:从
Object
SAXParseFactory
?我相信这是一个向下转换(向上转换总是被允许的;向下转换涉及类型检查,这里确实是这样-如果
t
不是一个扩展
SAXParseFactory
)的类,你会得到一个强制转换异常。{JLS使用这些术语,它使用缩小/扩大引用转换}@CarlosHeuberger是的,这是旧代码,是的,这是下档。我想,这个新版本将使用泛型类。然而,我的语句通常是指(JXSAXParserFactory扩展了SAXParserFactory),而不是指这一行code@LppEdd“这一行返回扩展SAXParserFactory的类的全名”,我们如何知道SAXParserFactory是由类的对象实现的?@Trisha mmh我不明白。什么意思?请尝试使用其他单词。@LppEdd,在上面的代码
className
中,返回新类实例的名称(
oracle.xml.jaxp.JXSAXParserFactory
)。这个类将是实现
SAXParserFactory
absact类的类。但这一实现在哪里进行?它说现在的
SAXParserFactory
是由
oracle.xml.jaxp.JXSAXParserFactory
实现的代码的哪一部分?
oracle.xml.jaxp.JXSAXParserFactory
102: Class t = (loader != null) ? loader.loadClass(className)
103:                            : Class.forName(className);
104: return (SAXParserFactory) t.newInstance();