Java: Каково различие между этими методами конструкции

Я использую атрибут Описания от Системы. Пространство имен ComponentModel. Просто украсьте перечисление и затем используйте этот код для получения его:

public static string GetDescription<T>(this object enumerationValue)
            where T : struct
        {
            Type type = enumerationValue.GetType();
            if (!type.IsEnum)
            {
                throw new ArgumentException("EnumerationValue must be of Enum type", "enumerationValue");
            }

            //Tries to find a DescriptionAttribute for a potential friendly name
            //for the enum
            MemberInfo[] memberInfo = type.GetMember(enumerationValue.ToString());
            if (memberInfo != null && memberInfo.Length > 0)
            {
                object[] attrs = memberInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);

                if (attrs != null && attrs.Length > 0)
                {
                    //Pull out the description value
                    return ((DescriptionAttribute)attrs[0]).Description;
                }
            }
            //If we have no description attribute, just return the ToString of the enum
            return enumerationValue.ToString();

        }

Как пример:

public enum Cycle : int
{        
   [Description("Daily Cycle")]
   Daily = 1,
   Weekly,
   Monthly
}

Этот код приятно обслуживает перечисления, где Вы не нуждаетесь в "Дружественном имени" и возвратите просто.ToString () перечисления.

5
задан MrHus 25 July 2009 в 16:31
поделиться

4 ответа

Они эквивалентны. Фактически, если вы скомпилируете два, вы увидите, что они генерируют один и тот же байт-код:

Publisher();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   new     #2; //class java/util/ArrayList
   8:   dup
   9:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
   12:  putfield        #4; //Field observers:Ljava/util/ArrayList;
   15:  return    
}

Учитывая, что это один и тот же код, явно не может быть разницы в скорости :)

Обратите внимание, что в C # они не совсем эквивалентны - в C # инициализатор для наблюдателей будет запускать перед вызовом базового конструктора; в Java они действительно такие же.

Что вы используете - дело вкуса. Если у вас есть несколько разных конструкторов, которые инициализируют переменную одинаково, имеет смысл использовать первую форму. С другой стороны, как правило, неплохо, если у вас есть несколько конструкторов, чтобы попытаться заставить большинство из них вызывать один «основной» конструктор, который и выполняет фактическую работу.

13
ответ дан 18 December 2019 в 07:55
поделиться

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

4
ответ дан 18 December 2019 в 07:55
поделиться

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

Рассмотрим следующий пример:

У меня есть тестовый класс:

public class Tester {
    Tester (String msg) {
        System.out.println(this + ":" + msg);

    }
}

У меня есть суперкласс:

public class Test  {

   protected Tester t1 = new Tester("super init block");

   Test (String constructorMsg) {
    new Tester(constructorMsg);
   }
}

и у меня есть подкласс:

Public class TestSub extends Test {

   private Tester t2 = new Tester("sub init block");

   TestSub(String constructorMsg) {
      super(constructorMsg);
      new TTester("sub constructor");
   }

}

В моем методе main я создать экземпляр TestSub :

public static void main(String[] args) {
    new TestSub("super constructor");

}

результаты будут следующими:

Tester@3e205f:super init block
Tester@bf73fa:super constructor
Tester@5740bb:sub init block
Tester@5ac072:sub constructor
2
ответ дан 18 December 2019 в 07:55
поделиться

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

Во втором примере вы можете быть более гибкими, если вы хотите изменить значение на основе аргументов конструктора.

1
ответ дан 18 December 2019 в 07:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: