Pointing to Abstract class

Trisha :

I've a basic knowledge of abstract class. Its that it cannot be instantiated itself but with class who is implemented it or the anonymous classes. I hope its right..!

But I've came across a below code.

SAXParserFactory factory = SAXParserFactory.newInstance(); 

And here's a newInstance sourc code:

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: 

If you see the code, there is a possibility of returning Reference type of SAXParserFactory is at line number 104 and 118.

At line 104, Its creating dynamic class. I want to know how newly created class can be casted into abstract class type SAXParserFactory ? I'm confused Here..!

And after Instantiating SAXParserFactory, below code runs

SAXParser saxParser = factory.newSAXParser();

So once SAXParserFactory is Instantiated, newSAXParser() method of abstract class SAXParserFactory class should be implemented before using it, But From where its being called ? Because the class who implements SAXParserFactory class is a class which is created at run time!

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

This line returns the full name of a class which extends SAXParserFactory.
An example might be

oracle.xml.jaxp.JXSAXParserFactory

Then

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

Asks the Classloader for the JXSAXParserFactory Class object (Class<JXSAXParserFactory>).

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

Class#newInstance is invoked, which in this case means the no-args constructor of JXSAXParserFactory is called.

Being the JXSAXParserFactory extends SAXParserFactory, it can be upcasted. This is the right term.

Extending means inheriting the father signature. Obviously by upcasting, you loose the additional exposed members of the sub-class.


SAXParserFactory#newSAXParser will always be limited at returning a SAXParser, but the underlying implementation (basically, the logic) will be different.

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=143873&siteId=1