Почему при использовании рефлексии для конструктора перечисления выводится больше параметров, чем их есть на самом деле?

В классе перечисления <br/> <pre><code class="java">public enum Cities {
	
Moscow(45), Novosibirsk(50);
	
private int regionCode;
	
Cities(int regionCode)
{
	this.regionCode = regionCode;		
}
}</code></pre> <br/> <br/> вы используете рефлексию для вызова его конструктора <br/> <pre><code class="java">Class&lt;?&gt; clazz = Cities.class;		
				
for(var c: clazz.getDeclaredConstructors())
{
	System.out.println(c.toGenericString());			
}</code></pre> <br/> <br/> В результате вы получаете вывод: <br/> private mainPackage.Cities(java.lang.String,int,int) <br/> <br/> Почему в выводе указано три параметра?
  • 13 октября 2024 г. 14:02
Ответы на вопрос 2
При использовании рефлексии для получения информации о конструкторах перечислений в Java, можно заметить, что выводимый список параметров может несколько отличаться от ожидаемого. В вашем случае вы видите три параметра для конструктора перечисления `Cities`, хотя сами вы определили только один параметр.

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

Вот основные моменты, чтобы объяснить это:

1. **Параметры перечисления**: Каждый элемент перечисления в Java является экземпляром класса, который автоматически получает неявные параметры. В вашем случае, при создании элементов `Moscow` и `Novosibirsk` происходит вызов конструктора, который помимо вашего параметра `int regionCode` также содержит дополнительные параметры для внутренней работы перечислений.

2. **Неявные параметры**: Java автоматически добавляет параметры для управления внутренним состоянием перечисления. Эти параметры могут быть связаны с логикой перечисления, например, они могут содержать информацию о самом перечислении, его порядковых номерах и состояниях.

3. **Иерархия классов**: Все перечисления являются подклассами `java.lang.Enum`, который сам по себе имеет свои собственные конструктивные нужды, и, следовательно, каждый конструктор перечисления должен учитывать это.

В вашем случае, вывод конструктора:
```
private mainPackage.Cities(java.lang.String,int,int)
```
указывает на то, что система создает дополнительный параметр типа `String`, который представляет имя перечисленного константа, и, возможно, еще один `int`, связанный с порядком перечисленных констант (или с каким-то другим внутренним механизмом Java).

Таким образом, вывод будет всегда включать эти дополнительные параметры, так как они необходимы для корректной работы механизма перечислений, даже если вы их не определяли в своем коде непосредственно.
Видимо ты забыл сохранить изменения в файле, тк этот код выдаёт как и ожидалось: 
private Cities(int)
https://java.godbolt.org/z/81xfr3fa4

enum Cities {

  Moscow(45),
  Novosibirsk(50);
	
  private int regionCode;
	
  Cities(int regionCode)
  {
	this.regionCode = regionCode;		
  }
}

class Main {

    public static void main(String[] args) {
        Class<?> clazz = Cities.class;		
				
        for(var c: clazz.getDeclaredConstructors())
        {
	        System.out.println(c.toGenericString());			
        }
    }
}
Похожие вопросы