Bri*_*ian 7 java oop compiler-errors instance-variables class-members
我有一些非常基本的Java问题,我想一劳永逸地理解这些问题.我有以下简短的代码:
public class VeryBasicJava{
public static void main(String[] args){
int x = 3;
int y = 4;
swapMe(x, y);
}
private void swapMe(int a, int b){
int a;
int b;
int tmp = a;
this.a = b;
this.b = a;
}
}
Run Code Online (Sandbox Code Playgroud)
当我编译时,我得到了可怕的"非静态方法swapMe(int,int)无法从静态上下文引用"错误.另外,我得到"a已在swapMe(int,int)中定义","b已经在swapMe(int,int)中定义"
我需要最终通过我的厚厚的头骨,是"非静态方法"错误,它是如何(为什么)引起的,以及如何避免它.
此外,我假设你可以做我试图用'swapMe'方法中的'a'和'b'变量做的事情.我以为我可以传入'a'和'b',但也创建新变量'a'和'b',并用"this"关键字引用它们.
我知道这是非常基本的,但这两个"问题"是我使用Java的两个主要问题,并且出于某种原因,似乎无法正确学习.
谢谢大家,花时间阅读本文.祝你有美好的一天.
Ósc*_*pez 11
这意味着该方法swapMe()
是一个实例方法,您需要一个VeryBasicJava
类的实例来调用它,如下所示:
VeryBasicJava instance = new VeryBasicJava();
int x = 3; int y = 4;
instance.swapMe(x, y);
Run Code Online (Sandbox Code Playgroud)
或者,您可以声明swapMe()
为static
,这样您就不需要先创建实例:
private static void swapMe(int a, int b)
Run Code Online (Sandbox Code Playgroud)
你只有一些小问题.您在评论中提到您对C有一些经验,因此我将尝试绘制一些基本的类比.阿static
法(如main
)用作普通的C函数.static
但是,非方法采用隐藏参数:this
,该参数指的是该方法要在其上运行的对象.当你编写这样的方法时:
private void swapMe(int a, int b) {
// ...
Run Code Online (Sandbox Code Playgroud)
它真的意味着这样的事情:
private void swapMe(VeryBasicJava this, int a, int b){
// ^^^^^^^^^^^^^^^^^^^^
// ...
Run Code Online (Sandbox Code Playgroud)
因为this
参数是专门处理的,所以static
在对象上调用非方法有一种特殊的语法:
myInstance.swapMe(someA, someB);
// ^^^^^^^^^^ ^^^^^ ^^^^^
// this a b
Run Code Online (Sandbox Code Playgroud)
并且因为swapMe
没有声明static
,它预计会被调用如上所述.
main
在VeryBasicJava
类中声明的事实并不意味着您自动拥有一个VeryBasicJava
对象.再次,因为main
它static
,它就像一个普通的C函数:
void VeryBasicJava_main(...) {
// ...
Run Code Online (Sandbox Code Playgroud)
要创建对象的实例,请使用new
:
VeryBasicJava vbj = new VeryBasicJava();
Run Code Online (Sandbox Code Playgroud)
这类似于malloc
C:
VeryBasicJava *vbj = malloc(sizeof(VeryBasicJava));
VeryBasicJava_construct(vbj);
Run Code Online (Sandbox Code Playgroud)
使用实例,您可以调用方法:
vbj.swapMe(spam, eggs);
Run Code Online (Sandbox Code Playgroud)
您的另一个问题有两个:范围和成员之一.适用范围,如你所知,是指其中一个变量存在.采取这个功能:
1: private void swapMe(int a, int b) {
2: int a;
3: int b;
4: int tmp = a;
5: this.a = b;
6: this.b = a;
7: }
Run Code Online (Sandbox Code Playgroud)
调用此方法时,会发生以下情况:
a
并且b
在给定调用中指定的值的情况下创建swapMe
.
使用默认值a
在本地创建一个new .这会隐藏参数,并且无法区分它们.swapMe
0
a
a
b
创建一个新的,也严格地是本地的.它也具有默认0
值,并隐藏参数b
.
tmp
已创建,其值设置为新声明的值a
,因此也是如此0
.
[ 见下文 ]
[ 见下文 ]
本地人a
并且b
不再存在,参数a
和b
.
在第5行和第6行中,您尝试使用语法this.a
来引用本地a
而不是参数.虽然这种语法存在于Java中,但它并不是你的意思.参数与局部变量的处理方式相同,因此不区分这两个类别,而是this.a
区分本地和成员.现在,会员是什么?好吧,说你的类声明包含变量声明:
class VeryBasicJava {
private int a;
private int b;
// ...
}
Run Code Online (Sandbox Code Playgroud)
这就像C中的成员声明struct
:
struct VeryBasicJava {
int a;
int b;
};
Run Code Online (Sandbox Code Playgroud)
这意味着当您创建以下实例时VeryBasicJava
:
VeryBasicJava vbj = new VeryBasicJava();
Run Code Online (Sandbox Code Playgroud)
该实例有它自己的变量a
和b
,它可以在任何非使用static
方法:
public void print() {
System.out.println("a is " + a);
System.out.println("b is " + b);
}
Run Code Online (Sandbox Code Playgroud)
如果您有一个与成员同名的局部变量,那么您必须使用this
明确声明您要引用该成员.这个完整的程序说明了如何声明,使用和区分成员和本地人.
class VeryBasicJava {
private int a;
private int b;
private int c;
public static void main(String[] args) {
VeryBasicJava vbj = new VeryBasicJava();
vbj.a = 3;
vbj.b = 4;
vbj.c = 5;
vbj.print(1);
}
public void print(int a) {
int b = 2;
System.out.println("a is " + a);
System.out.println("b is " + b);
System.out.println("c is " + c);
System.out.println("this.a is " + this.a);
System.out.println("this.b is " + this.b);
System.out.println("this.c is " + this.c);
}
}
Run Code Online (Sandbox Code Playgroud)
它会产生这个输出:
a is 1
b is 2
c is 5
this.a is 3
this.b is 4
this.c is 5
Run Code Online (Sandbox Code Playgroud)
我希望这些例子和解释都有帮助.