Answers:
您必须了解一个类与该类实例之间的区别。如果您在街上看到一辆汽车,即使您看不到哪种型号或类型,也会立即知道这是一辆汽车。这是因为您将看到的内容与“汽车” 类进行了比较。该类包含与所有汽车相似的类。将其视为模板或想法。
同时,您看到的汽车是“汽车”类的一个实例,因为它具有您期望的所有属性:有人驾驶它,它有引擎,车轮。
因此,该班级说“所有汽车都有颜色”,实例说“这辆特定的汽车是红色的”。
在OO世界中,您定义类,并在类内部定义type字段Color
。当实例化该类时(创建特定实例时),将为该颜色保留内存,并且可以为该特定实例指定颜色。由于这些属性是特定的,因此它们是非静态的。
静态字段和方法与所有实例共享。它们用于特定于类而不是特定实例的值。对于方法,这通常是全局辅助方法(如Integer.parseInt()
)。对于字段,通常是常量(例如汽车类型,即您的集合有限且不经常更改的东西)。
为了解决您的问题,您需要实例化类的实例(创建对象),以便运行时可以为该实例保留内存(否则,不同的实例会相互覆盖您不想要的实例)。
在您的情况下,请尝试以下代码作为起点:
public static void main (String[] args)
{
try
{
MyProgram7 obj = new MyProgram7 ();
obj.run (args);
}
catch (Exception e)
{
e.printStackTrace ();
}
}
// instance variables here
public void run (String[] args) throws Exception
{
// put your code here
}
新main()
方法创建了它所包含的类的一个实例(听起来很奇怪,但是由于main()
是用该类而不是用该实例创建的,所以可以做到这一点),然后调用一个实例方法(run()
)。
静态字段和方法连接到类本身而不是其实例。如果您有一个class A
,一个“ normal”方法b
和一个static方法c
,并且创建了a
该类的实例A
,则对A.c()
和的调用a.b()
是有效的。方法c()
不知道连接了哪个实例,因此它不能使用非静态字段。
为您提供的解决方案是使字段为静态,或者使方法为非静态。然后,您的主体可能看起来像这样:
class Programm {
public static void main(String[] args) {
Programm programm = new Programm();
programm.start();
}
public void start() {
// can now access non-static fields
}
}
的static
关键字修改类内的方法或可变的生命周期。static
在加载类时会创建一个方法或变量。static
仅当将类实例化为对象(例如,通过使用new
运算符)时,才会创建未声明为的方法或变量。
从广义上讲,类的生命周期为:
new
运算符使用该类创建一个对象,以将该类的实例作为实际对象,然后对该对象进行处理为了有一个应用程序的初始入口点,Java采用了以下约定:Java程序必须具有一个类,该类包含具有约定名称或特殊名称的方法。这种特殊方法称为main()
。由于无论是否已实例化包含main方法的类都必须存在该方法,因此main()
必须使用static
修饰符声明该方法,以便在加载该类后即可使用该main()
方法。
结果是,当您通过命令行启动Java应用程序时,java helloworld
会发生一系列操作。首先,将启动并初始化Java虚拟机。接下来,将包含编译后的Java代码的helloworld.class文件加载到Java虚拟机中。然后,Java虚拟机将在helloworld
名为的类中寻找一个方法main(String [] args)
。static
即使实际上尚未将类实例化为对象,此方法也必须存在。Java虚拟机不会通过从类创建对象来创建该类的实例。它只是加载类并从该main()
方法开始执行。
因此,您需要创建一个类的实例作为一个对象,然后可以访问该类的方法和变量(尚未用static
修饰符声明)。一旦Java程序开始使用该main()
函数,您就可以使用具有修饰符的任何变量或方法,static
因为它们作为要加载的类的一部分存在。
但是,在main()
方法之外的,没有static
修饰符的类的变量和方法在将类的实例创建为main()
方法内的对象之前不能使用。创建对象后,您可以使用对象的变量和方法。static
Java编译器会在编译时尝试尝试使用不带修饰符的类的变量和方法,而这些变量和方法不经过类的对象,并且在编译时会被标记为错误。
import java.io.*;
class HelloWorld {
int myInt; // this is a class variable that is unique to each object
static int myInt2; // this is a class variable shared by all objects of this class
static void main (String [] args) {
// this is the main entry point for this Java application
System.out.println ("Hello, World\n");
myInt2 = 14; // able to access the static int
HelloWorld myWorld = new HelloWorld();
myWorld.myInt = 32; // able to access non-static through an object
}
}
让我们首先分析您的程序。在您的程序中,第一个方法是main()
,并记住它是静态方法...然后声明该方法的局部变量(compareCount,low,high等。)。此变量的范围仅是声明的方法,无论它是静态方法还是非静态方法。因此,您不能在该方法之外使用这些变量。这是您犯的基本错误。
然后我们到下一点。你告诉静静杀死了你。(这可能会杀死您,但是只会使您的程序生死!!)首先,您必须了解基本知识。*静态方法仅调用静态方法,而仅使用静态变量。*静态变量或静态方法不依赖于该类的任何实例。(即,如果更改静态变量的任何状态,它将反映在该类的所有对象中)*因此,您将其称为类变量或类方法。“ static”关键字还有很多。我希望你现在明白了。首先更改变量的范围,并将其声明为静态变量(以便能够在静态方法中使用它)。
对您的建议是:您误解了变量和静态功能范围的概念。对此有个清晰的想法。
最基本的是静态变量或静态方法在类级别。类级变量或方法先于实例级方法或变量被加载。显然,未加载的东西不能使用。因此,java编译器不让运行时要处理的事情在编译时解决。这就是为什么它给您带来错误,无法从静态上下文引用非静态内容的原因。您只需要阅读有关类级别范围,实例级别范围和本地范围的信息。
为了能够从您的静态方法访问它们,它们必须是静态成员变量,如下所示:
public class MyProgram7 {
static Scanner scan = new Scanner(System.in);
static int compareCount = 0;
static int low = 0;
static int high = 0;
static int mid = 0;
static int key = 0;
static Scanner temp;
static int[]list;
static String menu, outputString;
static int option = 1;
static boolean found = false;
public static void main (String[]args) throws IOException {
...
现在,您可以在方法中添加/使用实例
public class Myprogram7 {
Scanner scan;
int compareCount = 0;
int low = 0;
int high = 0;
int mid = 0;
int key = 0;
Scanner temp;
int[]list;
String menu, outputString;
int option = 1;
boolean found = false;
private void readLine() {
}
private void findkey() {
}
private void printCount() {
}
public static void main(String[] args){
Myprogram7 myprg=new Myprogram7();
myprg.readLine();
myprg.findkey();
myprg.printCount();
}
}
我将尝试向您解释静态内容。首先,静态变量不属于该类的任何特定实例。它们以班级名称识别。静态方法也不再次属于任何特定实例。他们只能访问静态变量。假设您调用MyClass.myMethod(),而myMethod是静态方法。如果在方法内部使用非静态变量,那么到底该如何使用哪个变量呢?这就是为什么您只能从静态方法中使用静态变量的原因。我再说一遍,它们不属于任何特定实例。
首先是要了解类实例与类本身之间的区别。一个类对某些属性进行建模,并在这些属性的上下文中模拟整个行为。实例将为这些属性定义特定的值。
在类的上下文中,而不是在类的实例的上下文中,任何与static关键字绑定的内容都可用
作为上述必然结果
静态字段/方法的生命周期等于应用程序的生命周期
例如,汽车具有属性颜色,并且表现出“运动”行为。汽车的一个实例是一辆以25kmph的速度行驶的红色大众甲壳虫。
现在,汽车的静态属性将是道路上的车轮数量(4),这将适用于所有汽车。
高温超导
由ClassLoader负责加载类文件。让我们看看在编写自己的类时会发生什么。
范例1:
class StaticTest {
static int a;
int b;
int c;
}
现在我们可以看到类“ StaticTest”具有3个字段。但是实际上不存在b,c成员变量。但是为什么要使用???。好吧,别担心。这里b,c是实例变量。因为实例变量在创建对象时获取内存。因此,此处b,c尚未获得任何内存。这就是为什么不存在b,c的原因。所以只有一个存在。对于ClassLoader,它只有一个有关a的信息。ClassLoader尚未识别b,c,因为它的对象尚未实例化。
让我们看另一个示例:示例2:
class StaticTest {
public void display() {
System.out.println("Static Test");
}
public static void main(String []cmd) {
display();
}
}
现在,如果我们尝试编译此代码,编译器将给出CE错误。CE:非静态方法display()不能从静态上下文中引用。
现在,对于ClassLoader来说,它看起来像:
class StaticTest {
public static void main(String []cmd) {
display();
}
}
在示例2中,CE错误是因为我们从静态上下文调用非静态方法。因此ClassLoader在编译时无法识别方法display(),因此发生了编译时错误。
这是为所有初学者介绍静态关键字的一个比较。
当您更多地使用类和对象时,您将清楚地了解它。
| * | 静态:可以使用类名调用静态项。
如果您在代码中观察到,则某些函数将直接使用类名进行调用,例如
NamCls.NamFnc();
System.out.println();
这是因为NamFnc和println将在它们之前使用关键字static声明。
| * | 非静态:非静态项目可以使用类变量来调用。
如果它不是静态的,则需要
该类的变量,在类变量之后放置点号,
然后调用函数。
NamCls NamObjVar = new NamCls();
NamObjVar.NamFnc();
| * | 类中的静态和非静态函数:
public class NamCls
{
public static void main(String[] args)
{
PlsPrnFnc("Tst Txt");
NamCls NamObjVar = new NamCls();
NamObjVar.PrnFnc("Tst Txt");
}
static void PlsPrnFnc(String SrgPsgVal)
{
System.out.println(SrgPsgVal);
}
void PrnFnc(String SrgPsgVal)
{
System.out.println(SrgPsgVal);
}
}
public class NamCls
{
public static void main(String[] args)
{
NamTicCls NamTicVaj = new NamTicCls();
NamTicVaj.PrnFnc("Tst Txt");
NamCls NamObjVar = new NamCls();
NamNicCls NamNicVar = NamObjVar.new NamNicCls();
NamNicVar.PrnFnc("Tst Txt");
}
static class NamTicCls
{
void PrnFnc(String SrgPsgVal)
{
System.out.println(SrgPsgVal);
}
}
class NamNicCls
{
void PrnFnc(String SrgPsgVal)
{
System.out.println(SrgPsgVal);
}
}
}
C
。但这不是一个很好的选择。尝试使用Java作为一种面向对象的语言来使用它。