У вас всего несколько мелких проблем. Вы упомянули в комментарии, что у вас есть некоторый опыт работы с C, поэтому я попытаюсь провести некоторые основные аналогии. Метод static
(такой как main
) ведет себя как обычная функция C. Однако метод, отличный от static
, принимает скрытый параметр: this
, который ссылается на объект, над которым должен работать этот метод. Когда вы пишете такой метод:
private void swapMe(int a, int b) {
// ...
Это действительно означает что-то вроде этого:
private void swapMe(VeryBasicJava this, int a, int b){
// ^^^^^^^^^^^^^^^^^^^^
// ...
Поскольку параметр this
обрабатывается особым образом, существует специальный синтаксис для вызова методов, отличных от static
, для объектов:
myInstance.swapMe(someA, someB);
// ^^^^^^^^^^ ^^^^^ ^^^^^
// this a b
И поскольку swapMe
не объявлен как static
, ожидается, что он будет вызываться, как указано выше.
Тот факт, что main
объявлен внутри класса VeryBasicJava
, не означает, что у вас автоматически есть VeryBasicJava
объект. Опять же, поскольку main
равно static
, это похоже на обычную функцию C:
void VeryBasicJava_main(...) {
// ...
Чтобы создать экземпляр объекта, вы используете new
:
VeryBasicJava vbj = new VeryBasicJava();
Это аналогично malloc
в C:
VeryBasicJava *vbj = malloc(sizeof(VeryBasicJava));
VeryBasicJava_construct(vbj);
С экземпляром вы можете вызвать метод:
vbj.swapMe(spam, eggs);
Другая ваша проблема двояка: одна касается области и членов. Область действия, как вы, возможно, знаете, относится к тому, где находится переменная. Возьмите эту функцию:
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: }
При вызове этого метода происходит следующее:
a
и b
создаются с учетом значений, указанных в вызове swapMe
.
Создается новый a
, локальный для 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;
// ...
}
Это похоже на объявления членов в C struct
:
struct VeryBasicJava {
int a;
int b;
};
Это означает, что при создании экземпляра VeryBasicJava
:
VeryBasicJava vbj = new VeryBasicJava();
Этот экземпляр имеет свои собственные переменные a
и b
, которые можно использовать в любом методе, отличном от static
:
public void print() {
System.out.println("a is " + a);
System.out.println("b is " + b);
}
Если у вас есть локальная переменная с тем же именем, что и у члена, вы должны использовать 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);
}
}
Он будет производить этот вывод:
a is 1
b is 2
c is 5
this.a is 3
this.b is 4
this.c is 5
Я надеюсь, что эти примеры и пояснения будут вам полезны.
person
Jon Purdy
schedule
19.03.2012