我观察了tomact目录结构发现只有jar文件,没有我们一般编写javase那样的编译后的class文件。
为何tomcat里面有些类会用发射,有些类直接使用new关键字。
1.反射
public void init() throws Exception { initClassLoaders(); Thread.currentThread().setContextClassLoader(catalinaLoader); SecurityClassLoad.securityClassLoad(catalinaLoader); // Load our startup class and call its process() method if (log.isDebugEnabled()) log.debug("Loading startup class"); Class<?> startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.newInstance(); // Object startupInstance = new org.apache.catalina.startup.Catalina(); // Set the shared extensions class loader if (log.isDebugEnabled()) log.debug("Setting startup class properties"); String methodName = "setParentClassLoader"; Class<?> paramTypes[] = new Class[1]; paramTypes[0] = Class.forName("java.lang.ClassLoader"); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; }
2.Catalina类:
protected Digester createStartDigester() { long t1=System.currentTimeMillis(); // Initialize the digester Digester digester = new Digester(); digester.setValidating(false); digester.setRulesValidation(true); HashMap<Class<?>, List<String>> fakeAttributes = new HashMap<>(); ArrayList<String> attrs = new ArrayList<>(); attrs.add("className"); fakeAttributes.put(Object.class, attrs); digester.setFakeAttributes(fakeAttributes); digester.setUseContextClassLoader(true); .............
如上图所示,在1图中可以直接使用 Object startupInstance = new Catalina();吗?
因为tomcat目录中没有Catalina这个类,但是有.jar文件中含有这个类,我们可以这样使用吗?
为何tomcat源码中 部分使用反射生成实例,而部分则使用new关键字呢?而且tomcat启动有一个函数的代码是把bin目录下的jar包全部加载 (没有加载全部的类) 又是为何呢?
看心情与情况.自己写代码就知道了.到时候自然知道.
该用什么的时候用什么就行.别纠结.
fangp
new 都是可以new的,但是有时候不需要new自己的类,因为Java这个东西有个特性叫多态,意为多种状态,可以让一个对象存在各个类的各个状态中。所以没必要去管这些 该怎么用 就怎么用 Java不是很难
多态可不是多种状态。
@Daniel Cai:
@钓一条大鱼: 人家也说了是字面意思。多种状态是指对象在不同时刻所持有的不同信息。
class User
{
private int Status;
}
多态则是指从相同对象派生或实现的不同。
interface ISoundable
{
void Play();
}
class Duck:ISoundable
{
public void Play()
{
Console.WriteLine("gaga");
}
class Cat...
}
用反射是运行时依赖,用new是编译时依赖.
主要在于
1 性能考虑
自行搜索
2 类加载器的考虑
假设A类中使用new 创建类C,那么C的类加载器是和 A一样的
假设A类中使用反射创建类C,那么C的类加载器是和 A可能是不一样的, C会使用当前的线程绑定类加载器
有几点考虑: