我不明白为什么main方法必须是静态的。我理解静态变量,但我很难掌握静态方法。是否存在静态方法,以便可以在两个不会相互冲突的类中创建两个具有相同名称的方法?
另外,我不明白为什么我不能创建静态构造函数。
有人可以帮助解释这个概念吗?
答案 0 :(得分:80)
Java有 [静态构造函数] static initialization blocks,可以将其视为“静态构造函数”:
class Foo {
static String Bar;
static {
// "static constructor"
Bar = "Hello world!";
}
}
在任何情况下,必须静态的主类中唯一的方法是main
方法。这是因为在没有的情况下调用首先创建“主类”的实例。一种常见的技术,也是我喜欢的技术,是快速走出的静态背景:
class Main {
int argCount;
// constructor
public Main (String[] args) {
// and back to boring ol' non-static Java
argCount = args.length;
}
void runIt () {
System.out.println("arg count: " + argCount);
}
// must be static -- no Main instance created yet
public static void main (String[] args) {
Main me = new Main(args);
me.runIt();
}
}
另外,静态与“名字冲突”无关。静态方法(或变量)只是不与类型的特定实例相关联的方法(或变量)。我建议您阅读Classes and Objects Java Tutorial和Understanding Instance and Class Variables部分。
快乐的编码。
答案 1 :(得分:24)
我正在分享“为什么java构造函数不是静态的”。
简单地说,“java构造函数总是非静态的”,因为,
构造函数的目的只是初始化/构造对象,并使继承成为可能。要做到这些,我们需要使用两个有用的java关键字(兼非静态变量),例如this和super。 我们将使用'this'来初始化对象。 我们/ Java将使用super(ofcourse super())来调用超类构造函数,以便首先创建超级对象(或Object类),然后创建子对象(因此继承) 如果构造函数是静态的,那么我们不能在构造函数中使用这两个关键字(非静态变量)(因为我们知道非静态的东西不能从静态上下文中引用)
所以java构造函数不应该是静态的。
答案 2 :(得分:7)
静态方法属于类,而不是对象。 main方法必须是静态的,因为在执行任何其他代码实例化任何对象之前,首先调用它。它提供了该程序的入口点。从对象的容器外部调用静态方法。静态类变量也是如此。整个类只存在一个副本,而不是成员变量,该变量为从类创建的每个对象创建一次。它们用于存储类的数据,例如已创建但未销毁的对象实例数。此数据属于该类。静态方法的一个很好的例子是单例模式,其中构造函数是私有的,只能由静态成员函数访问。类外的函数将无法复制此功能。此方法作用于类数据和对象,因此逻辑上属于同一个类。这一切都归结为封装。一个班级只对自己负责,只知道自己。
另一方面,对象方法意味着对与类的一个实例(对象)相关联的数据进行操作。构造函数是用于初始化对象并将其数据设置为初始状态的代码。在分配内存以存储新对象后立即(并自动)执行它们。即使您没有明确定义构造函数,也会执行一种“默认构造函数”,以便将对象的成员变量和对象的方法代码映射到新对象。
希望这有帮助。
答案 3 :(得分:7)
构造函数用于创建对象。
静态通常对所有对象都相同。
因此,如果我们有静态构造函数,则创建一个对象会影响所有其他现有对象。
静态方法仅引用静态变量。因此,您为创建对象提供的所有初始参数都将针对所有对象进行更改。没有必要创建类似的对象。
希望这有助于.... :)
答案 4 :(得分:1)
构造函数是对象的属性,而静态与对象无关。这就是静态构造函数之类的原因。但是我们有静态块来执行与构造函数类似的任务,即字段的初始化等。
答案 5 :(得分:1)
Bruce Eckel撰写的《 Thinking in Java,第4版》第272页上说:
²即使static关键字不是显式的,构造方法也是一个静态方法。准确地说,是在访问类的任何静态成员时首先加载该类。
更多上下文。
...每个类的已编译代码位于其自己的单独文件中。在需要代码之前,不会加载该文件。通常,您可以说“在首次使用时就加载了类代码”。通常是在构造该类的第一个对象时,但在访问静态字段或静态方法时也会发生加载。²
如果您考虑说静态方法不能使用同一类的非静态方法的规则,这很有道理。几个星期前,当我不明白如何使用Singleton模式时,如何在用于创建该类的新实例的静态方法中访问构造函数,使我产生了疑问。今天,我翻阅了这本书,偶然发现了这个解释。
从某种意义上讲,如果构造函数不是静态的,则首先需要该类的实例才能访问它,但是我想这可能会引发关于鸡肉的古老讨论。或鸡蛋。
希望有帮助!
答案 6 :(得分:0)
我写了一个简单的例子作为昨天相关问题的答案,可能有助于使事情更容易理解:what's the point of java constructor?
静态方法的要点是可以在不创建类实例的情况下调用它们,而“普通”实例方法与实例相关,并且不能在没有实例的情况下调用它们。
由于Main类的Main方法是程序的入口点,因此无法创建任何实例,因此您无法通过实例访问它。因此,它是静态的,因此它可以作为程序的开始运行。
答案 7 :(得分:0)
只需看一下这个链接,它肯定会帮助您理解: Why can't make a constructor static?
和
在创建对象时,在运行时调用构造函数。 所有对象的静态都相同,但所有对象都有自己的状态和属性。 因此,如果我们有静态构造函数,则创建一个对象会影响所有其他现有对象。 注意:static是类级别,而构造函数与对象相关。
e.g。
public class Foo
{
String name;
int id;
// define constructors
Foo (String name, int id)
{
this.name = name;
this.id = id;
}
p s v m(String[] arg)
{
Foo f1 = new Foo("Amit",001);
Foo f2 = new Foo("Rahul",002);
}
}
如果我们创建静态构造函数,那么两个对象(f1也)将包含有关name和id的最后更新值Rahul和002。
答案 8 :(得分:0)
构造函数不能是静态的,因为在OO语言中,创建对象的过程如下:
构造函数不会在其他任何地方使用(并且类型安全的语言应该强制执行此操作),因此遵循构造函数将始终在非静态上下文中调用。
如果构造函数是静态的,它将不会接收对新分配的对象的引用,因此无法初始化它。
因此,构造函数总是非静态的(因为它总是从非静态上下文调用)并且必须始终是非静态的(否则它将无法执行其任务)。
答案 9 :(得分:0)
main(String[])
方法有一个特定的原型,由Java运行时环境的工作方式决定。从命令行调用java MyApplication
时,Java VM将查找该类中包含的静态main(String[])
方法,以便执行该应用程序。如果找不到该方法,则Java VM无法将该类作为应用程序运行。这就是语言的定义方式。这也意味着Java VM 不会创建应用程序类的实例以便运行它。
现在,如果您希望您的类既可以作为独立应用程序使用,也可以作为由其他东西创建的实例,那么您可以让您的类实现Runnable
接口,并提供{{1在新实例上执行main
方法的方法。
run
现在任何类都可能创建public class MyRunnableThing implements Runnable
{
// Define whatever variables your runnable thing needs here as
// private instance fields.
/** Fulfills requirements of Runnable interface. */
public void run()
{
System.out.println( "I'm running..." ) ;
}
/** Also makes the class runnable from the console. */
public static void main( String[] args )
{
MyRunnableThing runMeNow = new MyRunnableThing() ;
runMeNow.run() ;
}
}
的实例,并使用其MyRunnableThing
方法生成相同的行为执行run()
。
另见:Working with Static Constructor in Java。 Q& A中的一些亮点:
答案 10 :(得分:0)
构造函数的目的是构造一个Object,即将类的实例变量初始化为默认值或初始化值。静态方法无法访问非静态实例变量。所以构造函数不是静态的。
答案 11 :(得分:0)
声明为static的方法不需要创建对象。由于我们没有为main方法创建对象,因此它被声明为static。
隐式调用构造函数来初始化一个对象,因此没有静态构造函数的目的。
答案 12 :(得分:0)
Java不允许将构造函数声明为静态。以下是原因。
静态表示相同的类。即无法继承静态方法。
对于静态,不能使用“ this”引用(关键字)。 “ this”始终链接到对象。构造函数始终属于某个对象。
如果构造函数是静态的,则子类的对象无法访问。如果构造函数允许使用static,则可以在类中但不能通过子类访问它。
答案 13 :(得分:0)
静态属于类,构造函数属于对象
我们知道静态方法,块或变量属于该类。而构造函数属于该对象,并在使用new运算符创建实例时调用。由于构造函数不是类属性,因此有理由认为它不能是静态的。
答案 14 :(得分:0)
构造函数既不是完全静态的(类级别)也不是完全静态的(实例级)。
this
。那么,为什么不能声明构造函数static
?
好吧,我的看法是,(冗余)static
关键字会造成混乱,并且没有任何作用。因此,他们决定不允许它。
关于静态初始化块可以视为构造函数的解释(IMO)在概念上是错误的。 (这类似于说实例初始化块是常规构造函数。这同样是错误的。)
静态初始化和构造 1 之间的主要区别是:
new
等效的类初始化功能,1-假设,如果显式的类初始化 ,则具有静态构造函数是有意义的。但是缩小规模是因为应用程序需要显式“构造”他们使用的所有类……这太可怕了。
2-如果可以动态加载类,则可以控制一定程度,但是即使在当前类加载器中已经加载了该类并对其进行了初始化,尝试控制初始化也会失败。
我不明白为什么主要方法必须是静态的。
必须要让main
方法充当应用程序的入口点。
问题是,如果main
是一个实例方法,则需要在您的入口点类的顶部创建一个实例来调用main
方法。但是,如何创建它呢?您会选择哪个构造函数?如果没有公共构造函数怎么办?
最重要的是,这就是Java的设计方式……早在1990年代……到目前为止,他们还没有看到改变这一需求的必要条件。
答案 15 :(得分:0)
第一,关键字static意味着所有标记为static的东西都必须是类级别的东西,只属于类。而构造函数属于对象,通常在我们使用时可能会调用它们new 运算符。所以我们现在知道构造函数甚至不是类属性,我们怎么可能将其标记为静态?
第二,静态构造函数违背了java中继承的全部目的。每次在我们创建子类对象之前,JVM都会自动调用超类构造函数来为要创建的子类对象做好准备.但是如果我们将构造函数标记为静态,子类将无法访问其超类的构造函数,因为它被标记为静态因此只属于类。