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();