I started learning a functional programming language(SML) and programmed in this language a little bit. And then i went started checking Java and i had this feeling that class fields seem like global variables and they complicate programming. For example i must read methods to see which one read/write them etc.
我开始学习函数式编程语言(SML)并用这种语言编写一些程序。然后我开始检查Java,我觉得类字段看起来像全局变量,它们使编程复杂化。例如,我必须阅读方法,以查看哪一个读/写它们等。
From what i have heard using global variables in programming languages like C is a bad idea. But what about Java class fields, aren't they something like global variables for all your class methods? Is it a bad idea to use fields? (Or maybe i have understand something wrong or i program in the "wrong way" Java)
从我所听到的,使用像C这样的编程语言中的全局变量是一个坏主意。但是Java类字段呢,它们不是像所有类方法的全局变量吗?使用字段是个坏主意吗? (或者我可能理解错误或者以“错误的方式”Java编程)
5 个解决方案
#1
3
Class
level variables are global variables in the context of the class. That is done to keep some state, you need to have them somewhere. In some cases, Class
level variables are considered bad practice though especially when they are not immutable.
类级变量是类的上下文中的全局变量。这是为了保持一些状态,你需要把它们放在某个地方。在某些情况下,类级变量被认为是不好的做法,尤其是当它们不是不可变的时。
#2
3
I assume by "class variables" you mean "static variables".
我假设“类变量”是指“静态变量”。
You ask "aren't they something like global variables for all your class methods?".
你问“他们不是所有类方法的全局变量吗?”。
Yes, you are right. Within the class the behave like globals with all their issues.
你是对的。在类中,行为像全局因素一样。
The difference is that your classes should not be as complex as whole programs and thus it would be easier to understand and fix the problems caused by them.
The less code can modify a variable the less cases you have to consider. Globals can be modified by arbitrary unknown code.
不同之处在于,您的类不应该像整个程序一样复杂,因此更容易理解和修复由它们引起的问题。代码越少,修改变量的情况就越少。 Globals可以通过任意未知代码进行修改。
It also makes absolute sense in some situations to have all instances of a class share a variable (e.g. a singleton). You just have to use it responsibly.
在某些情况下,使一个类的所有实例共享一个变量(例如单例)也是绝对有意义的。你只需要负责任地使用它。
Should you not use them?
No, you can use them. But limit their visibility to the needed minimum so they don't become 'de facto' globals.
Also make them final if possible.
你不应该使用它们吗?不,你可以使用它们。但是将它们的可见性限制在所需的最小值,因此它们不会成为“事实上的”全局变量。如果可能的话,也让他们最终。
#3
2
I would say that you don't quite understand the way Java (or any other object oriented language) works.
我会说你不太了解Java(或任何其他面向对象语言)的工作方式。
In object oriented languages, classes represent different types of things you may need in your whole program. It's better to ilustarte this with an example. Let's say in your program you are going to model cars.
在面向对象语言中,类表示整个程序中可能需要的不同类型的事物。最好通过一个例子来说明这一点。让我们在你的程序中说你要模拟汽车。
You would have a Car class, and would create a new object (a new instance) of the Car class to represent each new car you need. The car itself is constituted by different components, you have wheels, a motor, windows, etc. So you would have classes for each of these components, and each car object would contain its own set of objects from all the different classes, ie:
您将拥有Car类,并将创建Car类的新对象(新实例)以表示您需要的每辆新车。汽车本身由不同的组件构成,你有*,电机,窗户等。所以你将拥有每个组件的类,每个汽车对象将包含来自所有不同类的自己的一组对象,即:
Car1 {
motor1
window1.1, window1.2
wheel1.1,wheel1.2
}
Car2 {
motor2
window2.1, window2.2
wheel2.1,wheel2.2
}
In this case, you would define each of the cars' components as class fields. These fields are for all effects 'global' in that they can be accessed from any of the methods in that class. The detail you seem to be missing is that each new object of this class has its own set of fields and methods. They don't share them, so each motor, set of wheels, etc., belongs to one instance of the Car class. So if in the car class you have a method called, lets say, deleteWindows(), which would get rid of all the windows, and you called that method on car2, this would not delete car1's windows.
在这种情况下,您可以将每个汽车的组件定义为类字段。这些字段适用于所有“全局”效果,因为可以从该类中的任何方法访问它们。您似乎缺少的细节是此类的每个新对象都有自己的字段和方法集。它们不共享它们,因此每个电机,一组*等属于Car类的一个实例。因此,如果在汽车类中你有一个方法,比如说,删除所有窗口的deleteWindows(),你在car2上调用了这个方法,这不会删除car1的窗口。
Another important detail is that you can define these variables with several 'prefixes' (methods too). First you have public and private (protected to, but I won't get into that). By declaring a variable as private, you are saying the only object who can access and change that variable is the one who owns it. A public variable on the other hand can be accessed and changed by any other object. They are accessible, but you have to explicitly say you want to change that object's variable (by writing objectsName.variable, in our case car1.motor).
另一个重要细节是您可以使用多个“前缀”(方法)来定义这些变量。首先你有公共和私人(受保护,但我不会进入)。通过将变量声明为私有,您可以说唯一可以访问和更改该变量的对象是拥有该变量的变量。另一方面,公共变量可以被任何其他对象访问和更改。它们是可访问的,但您必须明确地说要更改该对象的变量(通过编写objectsName.variable,在我们的例子中为car1.motor)。
You can also have variables/methods that are shared by all instances of a class. To do this you declare them as static (these effectively belong to the class and not to any object of tha class in particular). Private/public still apply, a private static variable is only accessible by instances of that class (and static methods of the same class), while public ones are accessible by any other class/object. In order to access them from outside the class they belong to, you use ClassName.variable/method (so Car.variable in the previous example).
您还可以拥有类的所有实例共享的变量/方法。为此,您将它们声明为静态(这些实际上属于类,而不是特定于任何类的对象)。私有/公共仍然适用,私有静态变量只能由该类的实例(以及同一类的静态方法)访问,而公共变量只能由任何其他类/对象访问。为了从它们所属的类外部访问它们,可以使用ClassName.variable / method(在前面的示例中为Car.variable)。
Sometimes you might want to have a class that would make no sense creating an instance of. I find I often need to create a Maths class which contains several mathematical operator that I want to use throughout the whole program. It makes no sense creating a Maths object, so you would just define all its methods as 'public static' and access them whenever you need in your other classes.
有时你可能想要一个没有意义创建一个实例的类。我发现我经常需要创建一个Maths类,其中包含我想在整个程序中使用的几个数学运算符。创建Maths对象没有任何意义,因此您只需将其所有方法定义为“public static”,并在其他类中随时访问它们。
I hope I have clreaded your doubt. Either way I would suggest you do some reading on object oriented programming, maybe get a book that teaches Java with a heavy initial focus on object orientation (OO), as even though it isn't a hard concept to grasp, it might be hard getting used to it and correctly programming in an OO language if you come from a non-OO background.
我希望我已经克服了你的疑虑。无论哪种方式,我建议你做一些关于面向对象编程的阅读,也许得到一本教授Java的书,重点关注面向对象(OO),尽管它不是一个难以理解的概念,但可能很难如果你来自非OO背景,那么习惯它并用OO语言正确编程。
You might want to look into BlueJ. It's a Java IDE which basically forces you to understand and use OO programming. It's not something I suggest using for too long, but it might be a good place to start until you get a good grasp on the OO basics.
你可能想看看BlueJ。它是一个Java IDE,它基本上迫使您理解和使用OO编程。这不是我建议使用太久的东西,但它可能是一个好的开始,直到你掌握了OO基础知识。
Zepee
#4
1
No, class fields are not global variables, though they could be misused for much the same purpose.
不,类字段不是全局变量,尽管它们可能被滥用于同样的目的。
Global variables are accessible from every scope. They tend to be writable from every scope as well. This makes large codebases difficult to understand and debug. Global variables also invite name*.
可以从每个范围访问全局变量。它们往往也可以从各个范围写入。这使得大型代码库难以理解和调试。全局变量也会邀请name*。
Class fields are in class scope. They tend to be encapsulated in a class, with private access, preventing access from outside the class. This limits direct access and modification to a small subset of code.
类字段在类范围内。它们倾向于封装在具有私有访问权的类中,从而阻止从类外部访问。这限制了对一小部分代码的直接访问和修改。
#5
0
But In Java whole program is not written with using a single Class. And it is constants(public static final fields) that are like global variables. And my advice is for you not concentrate on each of this single part of the java, what good about the java is the what it deliver as a whole. Because that's when you see the impartance of each of this features of java.
但是在Java中,整个程序不是使用单个类编写的。它是常量(公共静态最终字段),就像全局变量一样。我的建议是你不要专注于java的这一部分,java的优点在于它作为一个整体提供的东西。因为当你看到java的每个特性的传播时。
#1
3
Class
level variables are global variables in the context of the class. That is done to keep some state, you need to have them somewhere. In some cases, Class
level variables are considered bad practice though especially when they are not immutable.
类级变量是类的上下文中的全局变量。这是为了保持一些状态,你需要把它们放在某个地方。在某些情况下,类级变量被认为是不好的做法,尤其是当它们不是不可变的时。
#2
3
I assume by "class variables" you mean "static variables".
我假设“类变量”是指“静态变量”。
You ask "aren't they something like global variables for all your class methods?".
你问“他们不是所有类方法的全局变量吗?”。
Yes, you are right. Within the class the behave like globals with all their issues.
你是对的。在类中,行为像全局因素一样。
The difference is that your classes should not be as complex as whole programs and thus it would be easier to understand and fix the problems caused by them.
The less code can modify a variable the less cases you have to consider. Globals can be modified by arbitrary unknown code.
不同之处在于,您的类不应该像整个程序一样复杂,因此更容易理解和修复由它们引起的问题。代码越少,修改变量的情况就越少。 Globals可以通过任意未知代码进行修改。
It also makes absolute sense in some situations to have all instances of a class share a variable (e.g. a singleton). You just have to use it responsibly.
在某些情况下,使一个类的所有实例共享一个变量(例如单例)也是绝对有意义的。你只需要负责任地使用它。
Should you not use them?
No, you can use them. But limit their visibility to the needed minimum so they don't become 'de facto' globals.
Also make them final if possible.
你不应该使用它们吗?不,你可以使用它们。但是将它们的可见性限制在所需的最小值,因此它们不会成为“事实上的”全局变量。如果可能的话,也让他们最终。
#3
2
I would say that you don't quite understand the way Java (or any other object oriented language) works.
我会说你不太了解Java(或任何其他面向对象语言)的工作方式。
In object oriented languages, classes represent different types of things you may need in your whole program. It's better to ilustarte this with an example. Let's say in your program you are going to model cars.
在面向对象语言中,类表示整个程序中可能需要的不同类型的事物。最好通过一个例子来说明这一点。让我们在你的程序中说你要模拟汽车。
You would have a Car class, and would create a new object (a new instance) of the Car class to represent each new car you need. The car itself is constituted by different components, you have wheels, a motor, windows, etc. So you would have classes for each of these components, and each car object would contain its own set of objects from all the different classes, ie:
您将拥有Car类,并将创建Car类的新对象(新实例)以表示您需要的每辆新车。汽车本身由不同的组件构成,你有*,电机,窗户等。所以你将拥有每个组件的类,每个汽车对象将包含来自所有不同类的自己的一组对象,即:
Car1 {
motor1
window1.1, window1.2
wheel1.1,wheel1.2
}
Car2 {
motor2
window2.1, window2.2
wheel2.1,wheel2.2
}
In this case, you would define each of the cars' components as class fields. These fields are for all effects 'global' in that they can be accessed from any of the methods in that class. The detail you seem to be missing is that each new object of this class has its own set of fields and methods. They don't share them, so each motor, set of wheels, etc., belongs to one instance of the Car class. So if in the car class you have a method called, lets say, deleteWindows(), which would get rid of all the windows, and you called that method on car2, this would not delete car1's windows.
在这种情况下,您可以将每个汽车的组件定义为类字段。这些字段适用于所有“全局”效果,因为可以从该类中的任何方法访问它们。您似乎缺少的细节是此类的每个新对象都有自己的字段和方法集。它们不共享它们,因此每个电机,一组*等属于Car类的一个实例。因此,如果在汽车类中你有一个方法,比如说,删除所有窗口的deleteWindows(),你在car2上调用了这个方法,这不会删除car1的窗口。
Another important detail is that you can define these variables with several 'prefixes' (methods too). First you have public and private (protected to, but I won't get into that). By declaring a variable as private, you are saying the only object who can access and change that variable is the one who owns it. A public variable on the other hand can be accessed and changed by any other object. They are accessible, but you have to explicitly say you want to change that object's variable (by writing objectsName.variable, in our case car1.motor).
另一个重要细节是您可以使用多个“前缀”(方法)来定义这些变量。首先你有公共和私人(受保护,但我不会进入)。通过将变量声明为私有,您可以说唯一可以访问和更改该变量的对象是拥有该变量的变量。另一方面,公共变量可以被任何其他对象访问和更改。它们是可访问的,但您必须明确地说要更改该对象的变量(通过编写objectsName.variable,在我们的例子中为car1.motor)。
You can also have variables/methods that are shared by all instances of a class. To do this you declare them as static (these effectively belong to the class and not to any object of tha class in particular). Private/public still apply, a private static variable is only accessible by instances of that class (and static methods of the same class), while public ones are accessible by any other class/object. In order to access them from outside the class they belong to, you use ClassName.variable/method (so Car.variable in the previous example).
您还可以拥有类的所有实例共享的变量/方法。为此,您将它们声明为静态(这些实际上属于类,而不是特定于任何类的对象)。私有/公共仍然适用,私有静态变量只能由该类的实例(以及同一类的静态方法)访问,而公共变量只能由任何其他类/对象访问。为了从它们所属的类外部访问它们,可以使用ClassName.variable / method(在前面的示例中为Car.variable)。
Sometimes you might want to have a class that would make no sense creating an instance of. I find I often need to create a Maths class which contains several mathematical operator that I want to use throughout the whole program. It makes no sense creating a Maths object, so you would just define all its methods as 'public static' and access them whenever you need in your other classes.
有时你可能想要一个没有意义创建一个实例的类。我发现我经常需要创建一个Maths类,其中包含我想在整个程序中使用的几个数学运算符。创建Maths对象没有任何意义,因此您只需将其所有方法定义为“public static”,并在其他类中随时访问它们。
I hope I have clreaded your doubt. Either way I would suggest you do some reading on object oriented programming, maybe get a book that teaches Java with a heavy initial focus on object orientation (OO), as even though it isn't a hard concept to grasp, it might be hard getting used to it and correctly programming in an OO language if you come from a non-OO background.
我希望我已经克服了你的疑虑。无论哪种方式,我建议你做一些关于面向对象编程的阅读,也许得到一本教授Java的书,重点关注面向对象(OO),尽管它不是一个难以理解的概念,但可能很难如果你来自非OO背景,那么习惯它并用OO语言正确编程。
You might want to look into BlueJ. It's a Java IDE which basically forces you to understand and use OO programming. It's not something I suggest using for too long, but it might be a good place to start until you get a good grasp on the OO basics.
你可能想看看BlueJ。它是一个Java IDE,它基本上迫使您理解和使用OO编程。这不是我建议使用太久的东西,但它可能是一个好的开始,直到你掌握了OO基础知识。
Zepee
#4
1
No, class fields are not global variables, though they could be misused for much the same purpose.
不,类字段不是全局变量,尽管它们可能被滥用于同样的目的。
Global variables are accessible from every scope. They tend to be writable from every scope as well. This makes large codebases difficult to understand and debug. Global variables also invite name*.
可以从每个范围访问全局变量。它们往往也可以从各个范围写入。这使得大型代码库难以理解和调试。全局变量也会邀请name*。
Class fields are in class scope. They tend to be encapsulated in a class, with private access, preventing access from outside the class. This limits direct access and modification to a small subset of code.
类字段在类范围内。它们倾向于封装在具有私有访问权的类中,从而阻止从类外部访问。这限制了对一小部分代码的直接访问和修改。
#5
0
But In Java whole program is not written with using a single Class. And it is constants(public static final fields) that are like global variables. And my advice is for you not concentrate on each of this single part of the java, what good about the java is the what it deliver as a whole. Because that's when you see the impartance of each of this features of java.
但是在Java中,整个程序不是使用单个类编写的。它是常量(公共静态最终字段),就像全局变量一样。我的建议是你不要专注于java的这一部分,java的优点在于它作为一个整体提供的东西。因为当你看到java的每个特性的传播时。