Можно ли инициализировать конечную переменную при создании объекта?

как это возможно, чтобы мы могли инициализировать конечную переменную класса во время создания объекта?

Кто-нибудь может объяснить, как это возможно? ...


person Shivam    schedule 03.09.2013    source источник
comment
Да, инициализируйте их в конструкторе создаваемого вами объекта класса.   -  person Nitesh Verma    schedule 03.09.2013
comment
Вы имеете в виду, как может Java разрешать присваивание в конструкторе ??   -  person Suresh Atta    schedule 03.09.2013
comment
Обычно следует публиковать сообщения в соответствии с sscce.org, поскольку это делает переполнение стека более эффективным. Разместите код, объясните, чего вы пытались достичь и что получили. Пожалуйста, помните об этом в будущем.   -  person Nitesh Verma    schedule 03.09.2013
comment
stackoverflow.com/questions/2339932/   -  person Nitesh Verma    schedule 03.09.2013


Ответы (9)


Вы должны инициализировать конечную переменную один раз и только один раз. Для переменной экземпляра это можно сделать тремя способами:

  1. в конструкторе
  2. в блоке инициализации экземпляра.
  3. когда ты объявляешь это

Вот пример всех трех:

public class X
{
    private final int a;
    private final int b;
    private final int c = 10;

    {
       b = 20;
    }

    public X(final int val)
    {
        a = val;
    }
}

В каждом случае код запускается один раз, когда вы вызываете new X(...), и нет возможности вызвать какой-либо из них снова, что удовлетворяет требованию инициализации, выполняемой один раз и только один раз для каждого экземпляра.

person TofuBeer    schedule 03.09.2013
comment
Сэр, как вы можете инициализировать переменную c во время объявления, потому что c не имеет назначенной памяти. - person Vinay Yadav; 03.03.2021
comment
@VinayYadav c - примитив, поэтому ему выделяется память, когда вы говорите новый - person TofuBeer; 04.03.2021
comment
но сэр, когда мы определяем наш класс, с ним не связано никакого пространства. Пространство будет выделено только тогда, когда мы создадим объект этого класса, но на данный момент мы не создавали никаких объектов - person Vinay Yadav; 04.03.2021
comment
@VinayYadav Верно, но присвоение происходит как часть процесса создания экземпляра, поэтому присвоение не произойдет, пока вы не создадите новый X (5) - person TofuBeer; 04.03.2021
comment
Хорошо, понял. Спасибо - person Vinay Yadav; 04.03.2021

Конечные переменные, которые не инициализируются во время объявления, называются пустой конечной переменной и должны быть инициализированы on all constructor either explicitly or by calling this(). В противном случае компилятор пожалуется на "final variable (name) might not be initialized".


Согласно Википедии

Конечная переменная может быть инициализирована только один раз, либо с помощью инициализатора, либо с помощью оператора присваивания. Его не нужно инициализировать в момент объявления: это называется "blank final" переменной. Пустая конечная переменная экземпляра класса должна быть определенно назначена в конце каждого конструктора класса, в котором она объявлена; аналогично, пустая конечная статическая переменная должна быть определенно назначена в статическом инициализаторе класса, в котором она объявлена; в противном случае в обоих случаях возникает ошибка времени компиляции.

Eg.

public class Sphere {

    // pi is a universal constant, about as constant as anything can be.
    public static final double PI = 3.141592653589793;  

    public final double radius;
    public final double xPos;
    public final double yPos;
    public final double zPos;

    Sphere(double x, double y, double z, double r) {
         radius = r;
         xPos = x;
         yPos = y;
         zPos = z;
    }

    [...]
}

Подробнее читайте на вики-странице http://en.wikipedia.org/wiki/Final_(Java)

person AurA    schedule 03.09.2013
comment
Спасибо, Аура, можете ли вы сказать мне, насколько мне известно, мы должны инициализировать конечную переменную, когда мы ее определяем, и не можем изменить ее значение, тогда как это возможно? Можете ли вы объяснить пустую конечную переменную-член. - person Shivam; 03.09.2013
comment
@ user1118930 Я обновил ответ в соответствии с вашими требованиями - person AurA; 03.09.2013

Если вы имеете в виду статический конечный член, вы можете использовать статический инициализатор:

class Example {
  public final static Map<String,Object> C;

  static {
    C = new HashMap<>();
    C.put("hi", 5);
  }
}
person Arne Burmeister    schedule 03.09.2013

Это возможно из-за способа внутренней работы JVM и способа разработки Java.

После того, как ваш код скомпилирован, сгенерированный файл .class будет содержать представление вашего кода в виде байт-кода. Файл класса - это не что иное, как набор байтов, структурированных в определенном порядке, который может интерпретироваться JVM.

В структуре файла классов вы сможете найти нечто, называемое постоянным пулом, которое представляет собой не что иное, как символьную справочную таблицу, используемую JVM при загрузке классов. Здесь будут найдены ваши окончательные переменные независимо от того, инициализированы ли они как литералы или нет.

Итак, теперь, когда вы это знаете, давайте продолжим и подумаем, что означает последний модификатор, он означает не что иное, как способ сообщить JVM, что в этом случае переменной будет присвоено значение, и как только это будет сделано, повторное присвоение операция с этой переменной не будет разрешена, поэтому, как указано в документации по языку Java, конечной переменной может быть присвоено значение один раз и только один раз.

Теперь, когда у вас есть эта предыстория, чтобы напрямую ответить на ваш вопрос:

Независимо от того, является ли ваша переменная объектом или примитивным типом, значение конечной переменной, которая не является членом класса (то есть не статическим), будет автоматически установлено JVM с использованием значения в пуле констант времени выполнения для вашего объекта ИЛИ, если это переменная не инициализируется при объявлении, тогда ее необходимо будет установить при запуске конструктора. Все это возможно, потому что Java была разработана таким образом, чтобы предоставить программистам некоторую гибкость при назначении переменных, чтобы избежать жесткого кодирования и предоставить способ назначать объекты конечным ссылкам.

В качестве последнего совета перестаньте думать в C ++ как о конечных переменных как о константах. Они могут показаться похожими, но это не так, с ними обращаются совершенно по-разному.

person bubooal    schedule 03.09.2013

Да, мы можем инициализировать конечную переменную класса во время создания объекта, когда вы это сделаете, это будет назначать конечное значение для каждого объекта для этой конечной переменной экземпляра (не конечной статической переменной) каждый раз, но как только значение будет присвоено объекту не подлежит изменению.

    class Demo
{
    public final int num;
    
    public Demo(final int n)
    {
        this.num = n;// this will assign a final value for each object now 
    }
    
}
public class Sample
{  public static void main(String[] args)
    {
        Demo d = new Demo(20);
        System.out.println(d.num);
        
        Demo d1 = new Demo(21);
        System.out.println(d1.num);
        
        d1.num=22;//Invalid will give error now because you are trying to change the final value for d1 object
        System.out.println(d1.num);
    }
} 
person Utkarsh Salaria    schedule 21.05.2021

Почему нет. Нравится

public class GenericFoo{

    final int var;

    GenericFoo(){
        var = 100;
    }

}
person rocketboy    schedule 03.09.2013

Значение final - это значение, которое может быть установлено только один раз и только в конструкторе. Нет причин, по которым конструктор не может установить любое значение, которое вам нравится.

Если бы у вас было значение, которое вы хотели бы сделать константой для всех экземпляров, вы бы сделали его static final и НЕ смогли бы установить его в конструкторе. Возможно, вы их путаете.

person Peter Lawrey    schedule 03.09.2013

Вы можете инициализировать окончательные переменные экземпляра до завершения работы конструктора.
Согласно JSL

Пустая конечная переменная экземпляра должна быть определенно назначена в конце каждого конструктора класса, в котором она объявлена; в противном случае возникает ошибка времени компиляции.

Пустая конечная переменная в Java - это конечная переменная, которая не инициализируется при объявлении

Итак, есть 2 способа сделать это.

способ 1: В конструкторе

class Program {
    final int i3;   
    Program() {
        i3 = 10;
    }
}

способ 2: в блоке экземпляра

class Program {
       final int i3;   
       {
             i3 = 10;
        }
    }
person Prabhaker A    schedule 03.09.2013

Как вы знаете, переменная экземпляра связана только с объектом класса, а ключевое слово final перед переменной означает, что вы не можете изменить значение переменной, поэтому переменная существует только тогда, когда объект создан, поэтому мы можем назначить конечное значение переменной тремя способами, как указано выше. перед созданием объекта (например, статическим блоком, когда вы объявляете) или во время создания объекта (например, через конструктор)

person Anish    schedule 07.11.2017