简体   繁体   English

为什么我们不能使用构造函数本身来初始化 servlet?

[英]why we can't initialize a servlet using constructor itself?

Why do we have to override init() method in Servlets while we can do the initialization in the constructor and have web container call the constructor passing ServletConfig reference to servlet while calling constructor?为什么我们必须覆盖 Servlet 中的 init() 方法,而我们可以在构造函数中进行初始化,并让 web 容器调用构造函数,同时调用构造函数将 ServletConfig 引用传递给 servlet?

Ofcourse container has to use reflection for this but container has to use reflection anyway to call a simple no-arg constructor当然容器必须为此使用反射,但容器无论如何都必须使用反射来调用简单的无参数构造函数

Since a constructor can not be part of an interface, it can not be "formally" specified within the Servlet API, unlike normal methods.由于构造函数不能是接口的一部分,因此与普通方法不同,它不能在 Servlet API 中“正式”指定。 Moreover, since Java has no destructors, a destroy method is needed anyway, so it defining the corresponding init method makes the API more consistent and easier to use.而且,由于Java没有析构函数,无论如何都需要一个destroy方法,所以定义了相应的init方法,使得API更加一致,使用起来更加方便。

Using reflection to detect/verify constructor parameters would just unnecessarily complicate things, and I don't see any added value.使用反射来检测/验证构造函数参数只会不必要地使事情复杂化,而且我看不到任何附加值。

Servlet object has a well-defined life cycle where creation and initialization steps are distinct. Servlet 对象具有明确定义的生命周期,其中创建和初始化步骤是不同的。 Usually you don't want to do heavy and unreliable work in constructors, eg getting DB connection pool or initializing cache.通常你不想在构造函数中做繁重和不可靠的工作,例如获取数据库连接池或初始化缓存。 You have a chance to do it after a Servlet object is successfully created.成功创建 Servlet 对象后,您就有机会执行此操作。

Also, here http://oreilly.com/catalog/jservlet/chapter/ch03.html is a historical reason:另外,这里http://oreilly.com/catalog/jservlet/chapter/ch03.html是一个历史原因:

The init() method is typically used to perform servlet initialization--creating or loading objects that are used by the servlet in the handling of its requests. init() 方法通常用于执行 servlet 初始化——创建或加载 servlet 在处理其请求时使用的对象。 Why not use a constructor instead?为什么不使用构造函数呢? Well, in JDK 1.0 (for which servlets were originally written), constructors for dynamically loaded Java classes (such as servlets) couldn't accept arguments.嗯,在 JDK 1.0(最初为它编写 servlet)中,动态加载的 Java 类(例如 servlet)的构造函数不能接受参数。

So, in order to provide a new servlet any information about itself and its environment, a server had to call a servlet's init() method and pass along an object that implements the ServletConfig interface.因此,为了向新的 servlet 提供有关其自身及其环境的任何信息,服务器必须调用 servlet 的 init() 方法并传递一个实现 ServletConfig 接口的对象。

Also, Java doesn't allow interfaces to declare constructors.此外,Java 不允许接口声明构造函数。 This means that the javax.servlet.Servlet interface cannot declare a constructor that accepts a ServletConfig parameter.这意味着 javax.servlet.Servlet 接口不能声明接受 ServletConfig 参数的构造函数。 It has to declare another method, like init().它必须声明另一个方法,例如 init()。 It's still possible, of course, for you to define constructors for your servlets, but in the constructor you don't have access to the ServletConfig object or the ability to throw a ServletException.当然,您仍然可以为您的 servlet 定义构造函数,但是在构造函数中,您无权访问 ServletConfig 对象或抛出 ServletException 的能力。

One reason is that you don't have access to the ServletConfig object in the constructor.原因之一是您无权访问构造函数中的 ServletConfig 对象。 The ServletConfig object is created after the constructor is called and before init() is called. ServletConfig 对象是在调用构造函数之后和调用 init()之前创建的。 So, you cannot access servlet init parameters in the constructor.因此,您无法在构造函数中访问 servlet init 参数。

Servlet implementation classes can have constructor but they should be using init() method to initialize Servlet because of two reasons, first you cannot declare constructors on interface in Java, which means you cannot enforce this requirement to any class which implements Servlet interface and second, Servlet require ServletConfig object for initialization which is created by container as it also has reference of ServletContext object, which is also created by container. Servlet 实现类可以有构造函数,但它们应该使用 init() 方法来初始化 Servlet,原因有两个,首先你不能在 Java 的接口上声明构造函数,这意味着你不能将此要求强制执行到任何实现 Servlet 接口的类,其次, Servlet 需要 ServletConfig 对象进行初始化,该对象由容器创建,因为它也有 ServletContext 对象的引用,该对象也是由容器创建的。

Servlet is an interface defined in javax.servlet package and HttpServlet is a class and like any other class in Java they can have constructor, but you cannot declare constructor inside interface in Java. Servlet 是在 javax.servlet 包中定义的接口,而 HttpServlet 是一个类,就像 Java 中的任何其他类一样,它们可以有构造函数,但不能在 Java 中的接口内部声明构造函数。 If you don't provide an explicit constructor than compiler will add a default no argument constructor in any Servlet implementation class.如果您不提供显式构造函数,那么编译器将在任何 Servlet 实现类中添加一个默认的无参数构造函数。 Another reason that you should not initialize Servlet using constructor because Servlets are not directly instantiated by Java code, instead container create there instance and keep them in pool.另一个不应该使用构造函数初始化 Servlet 的原因是因为 Servlet 不是由 Java 代码直接实例化的,而是容器在那里创建实例并将它们保存在池中。 Since containers from web servers like Tomcat and Jetty uses Java Reflection for creating instance of Servlet, presence of no argument constructor is must.由于来自 Tomcat 和 Jetty 等 Web 服务器的容器使用 Java 反射来创建 Servlet 实例,因此必须存在无参数构造函数。 So, by any chance if you provide a parametric constructor and forget to write a no argument constructor, web container will not be able to create instance of your Servlet, since there is no default constructor.因此,万一您提供参数构造函数而忘记编写无参数构造函数,Web 容器将无法创建 Servlet 的实例,因为没有默认构造函数。 Remember Java compiler doesn't add default no argument constructor, if there is a parametric constructor present in class.请记住,如果类中存在参数构造函数,则 Java 编译器不会添加默认的无参数构造函数。 That's why it's not advised to provide constructor in Servlet class.这就是为什么不建议在 Servlet 类中提供构造函数的原因。

In JDK 1.0 (for which servlets were originally written), constructors for dynamically loaded Java classes (such as servlets) couldn't accept arguments.在 JDK 1.0(最初为其编写 servlet)中,动态加载的 Java 类(例如 servlet)的构造函数不能接受参数。 So, in order to provide a new servlet any information about itself and its environment, a server had to call a servlet's init() method and pass along an object that implements the ServletConfig interface.因此,为了向新的 servlet 提供有关其自身及其环境的任何信息,服务器必须调用 servlet 的 init() 方法并传递一个实现 ServletConfig 接口的对象。 see: doc见:文档

In detail,If you want to dynamically load a Java class, you should use the following method:详细来说,如果你想动态加载一个Java类,你应该使用下面的方法:

Class<MyClass> clazz = MyClass.class;
Constructor<MyClass> ctor = clazz.getDeclaredConstructor(String.class);
MyClass instance = ctor.newInstance("foo");

But, the method which returns a Constructor object in the Class class has been written since jdk1.1.但是,在Class类中返回Constructor对象的方法是从jdk1.1开始写的。 In jdk1.0, you can only use the following parameterless method:在jdk1.0中,只能使用以下无参方式:

Object newObject = Class.forName(strFullyQualifiedClassName).newInstance();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我们不能调用servlet构造函数而不是init方法来初始化config参数? - Why can not we call servlet constructor instead of init method to initialize the config parameters? 为什么我无法在Servlet中初始化Mongo - Why I can't initialize a Mongo in Servlet 使用像 INTEGR_ONE 这样的常量是个好方法,为什么我们不能使用 1 本身呢? - Is using constants like INTEGR_ONE a good way, why can't we use the 1 itself? 为什么我们可以在java中初始化数据成员时需要默认构造函数? - Why do we need default constructor when we can initialize data members in java? 我们可以在servlet中创建非参数化的构造函数吗? - Can we create a non parameterized constructor in servlet? 我们可以不在 Trie 构造函数中初始化引用数组吗 - Can we not initialize reference array in Trie constructor 为什么我们不能在Java构造函数中传递字符串 - why can't we pass string in java constructor 为什么我们不能在Java中使用抽象构造函数? - Why can't we have abstract constructor in java? 为什么我们不能在 java 的 class 构造函数中声明变量? - Why we can't declare variables in class constructor in java? 为什么即使我们输入了所有的可能性,我们也不能根据条件初始化和访问变量? - Why we can't initialize and access a variable based on a condition even after we type all the possibilities?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM