Общедоступная переменная Java равна нулю в частном классе

Это мой второй день работы с java, и я не могу понять, почему публичная переменная равна 0 в частном методе. Код выглядит следующим образом:

public class SomeClass {

    public int[][] gridArray; 

    private int N;

    public methodOne(int N){

        gridArray = new int[N][N];

    }

    private boolean isValid(int i, int j){
        if (i < 0 || i > N || j < 0 || j > N){
            StdOut.println(i + " and " + j + " and "+ N);
            throw new java.lang.IndexOutOfBoundsException();
        } else{return true;}
    }

    public static void main(String[] args) {
        int N = 5;

    // some code for getting indices

    }

Итак, я создаю массив и ввожу индексы и проверяю, действительны ли эти индексы или они находятся за пределами границ. Я всегда получаю исключение, потому что в методе isValid N равно 0, несмотря на объявление в main.


person Fortyq    schedule 01.07.2014    source источник
comment
возможный дубликат Java, что фигурные скобки означают сами по себе?   -  person Damian Leszczyński - Vash    schedule 01.07.2014
comment
кстати, где вы звоните isValid?   -  person JohnnyAW    schedule 01.07.2014
comment
У вас здесь проблемы с деревом. Вы смешиваете статическую концепцию с объектом. Если основной не был статическим, у вас будет проблема с скрытием переменных. Последнее - это то, что вы используете для простых имен переменных. Вам следует скорее следовать простому руководству.   -  person Damian Leszczyński - Vash    schedule 01.07.2014
comment
всегда получать исключение какое исключение, где?   -  person Raedwald    schedule 01.07.2014
comment
Это мой второй день работы с java. SO - не лучший ресурс для тех, кто плохо знаком с программированием или языком программирования. Прочтите и следуйте некоторым учебным пособиям и книгам.   -  person Raedwald    schedule 01.07.2014


Ответы (3)


N в main не то же самое N, что и в SomeClass.

Это связано с концепцией объема.

N в main является локальным для этого метода. Другими словами, вне этого метода его не существует.

N в классе SomeClass - это переменная экземпляра. Если вы создаете экземпляр SomeClass, он получает свою собственную версию N, которая идет вместе с ним.

public class SomeClass {
    private static int static_member;
    private int instance_member;

    public void instance_method() {
        // this is completely different from the other
        // local_variable in static_method()
        int local_variable;

        static_member = 1; // legal
        SomeClass.static_member = 1; // legal
        instance_member = 1 // legal
        this.instance_member = 1 // legal
    }

    public static void static_method() {
        // this is completely different from the other
        // local_variable in instance_method()
        int local_variable;

        static_member = 1; // legal
        SomeClass.static_member = 1; // legal
        instance_member = 1 // not legal, in a static method, there is no instance
    }
}

Просто потому, что у некоторой переменной одно и то же имя, если она находится в другой области видимости, это разные переменные.


Помните, что класс похож на шаблон для объектов. Вы создаете объект, создавая экземпляр класса.

Вам нужно создать экземпляр SomeClass в main, а затем использовать его. Вам также нужно кое-как настроить значение N. Обычно это делается с помощью конструктора (специальной функции, которая отвечает за создание экземпляров классов). Вам также необходимо сделать isValid() общедоступным методом вашего класса, чтобы его можно было вызывать вне вашего класса.

public class SomeClass {

    public int[][] gridArray; 

    private int N;

    public SomeClass(int N){
        this.N = N;
        this.gridArray = new int[N][N];
    }

    public boolean isValid(int i, int j){
        if (i < 0 || i >= N || j < 0 || j >= N){
            System.out.println(i + " and " + j + " and "+ N);
            throw new IndexOutOfBoundsException();
        } else{return true;}
    }

    public static void main(String[] args) {
        SomeClass instance = new SomeClass(5);
        instance.isValid(4,4);
    }
}

Наконец, ваша логика верна, неверна. Если N = 5, ваши проверки верхней границы позволят получить индекс 5, но максимальный индекс равен 4. Я также исправил это выше.

person Jamie Cockburn    schedule 01.07.2014
comment
как мне сделать их такими же? - person Fortyq; 01.07.2014
comment
Сумайя Кумар, он не может использовать это, так как главное статично. - person Damian Leszczyński - Vash; 01.07.2014
comment
@SoumyaKumar N не статичен, ему нужно создать объект для доступа к нему - person JohnnyAW; 01.07.2014

Разница заключается в переменной, определенной как переменная экземпляра и переменная метода.

private int N;

Эта переменная N определяется как поле memmber (непосредственно внутри класса), это переменная экземпляра.

int N = 5;

Этот int N определен в основном методе, это переменная метода.

Обе переменные имеют разную область видимости и не могут иметь одно и то же значение.

person Mandar Pandit    schedule 01.07.2014

ваша проблема в том, что объемы разные:

  • внутри конструктора используется аргумент int N. Таким образом, компилятор использует эту переменную для инициализации массива.

  • поле private int N в классе не создается. Поэтому метод isValid использует значение поля класса по умолчанию.

  • внутри основной функции вы создаете экземпляр другой переменной

В результате возникает проблема, заключающаяся в том, что на самом деле у вас есть 3 разных N внутри кода.

если вы поместите this.N = N внутрь methodOne и дадите ему тип возврата (void), все должно быть в порядке

person paubo147    schedule 01.07.2014
comment
не имелось ввиду внутри основного метода. Думал, что это будет конструктор, но, видимо, это просто еще один метод. - person paubo147; 01.07.2014