Есть ли эквивалент Java или методология для ключевого слова typedef в C ++?

196

Исходя из фона C и С++, я нашел разумное использование typedef невероятно полезным. Знаете ли вы, как добиться аналогичной функциональности в Java, будь то механизм Java, шаблон или какой-либо другой эффективный способ, который вы использовали?

  • 6
    Можно использовать typedef или много других вещей, хороших и плохих, хотя не все согласны с тем, что есть что. Не могли бы вы сказать, какие аспекты typedef вы считаете ценными? Таким образом, мы можем либо рассказать вам, как получить подобные эффекты в Java, либо почему вы не хотите делать это в Java. Под подборкой ответов ниже каждого предполагается, что вы говорите о любимом (или наиболее ненавистном) использовании автора.
  • 3
    Мне нравится печатать собственные типы, если позже я смогу превратить их в класс. typedef IndexT int; например. Позже, если я хочу, чтобы IndexT был классом, я просто реализую его и удаляю typedef. Это помогает с сокрытием информации.
Показать ещё 3 комментария
Теги:
design-patterns
typedef

11 ответов

103
Лучший ответ

Java имеет примитивные типы, объекты и массивы и что он. Нет typedefs.

  • 27
    Я думаю, что большинство людей хотят, чтобы typedef переопределял boolean на bool .
  • 58
    @ TomášZato Я не знаю большинства людей, но по моему опыту, это полезно для добавления семантики, такой как: typedef int PlayerID который позволяет компилятору гарантировать, что идентификаторы PlayerID не используются взаимозаменяемо с другими int, а также делает код намного более читаемый для человека. По сути, это как enum, но без ограниченного набора значений.
Показать ещё 5 комментариев
77

Если это то, что вы имеете в виду, вы можете просто расширить класс, который вы хотите ввести typedef, например:

public class MyMap extends HashMap<String, String> {}
  • 3
    Я бы поспорил, является ли это более анти-паттерном, чем использование typedef в C.
  • 19
    Это определенно так - у typedef нет проблем, описанных в статье для этих поддельных классов (и они вполне реальны).
Показать ещё 8 комментариев
14

В java от 1.6 нет typedef, вы можете сделать класс-оболочку для того, что хотите, поскольку вы не можете подклассифицировать конечные классы (Integer, Double и т.д.)

  • 2
    Ссылочная статья о шаблонах основана на предположении, что вы просто хотите сократить ввод текста (что на самом деле скрыло бы полезную информацию о типе). Реальное использование, которого хочет большинство людей, - устранение неоднозначности типов и предоставление компилятору своей работы за вас. Смотрите IndexT выше. public Invoice fetchInvoiceItem (String, String, String); в сравнении с общедоступным счетом fetchInvoiceItem (CustomerId, InvoiceId, InvoiceLineItemId); Явные типы плюс конвертеры / валидаторы делают программирование веб-API, где ВСЁ начинается с String, намного безопаснее.
  • 0
    Нет оператора oveloading в Java, так что это уродливо
3

Действительно, единственное использование typedef, которое переносится в Javaland, - это сглаживание, то есть предоставление одного и того же класса нескольких имен. То есть, у вас есть класс "A", и вы хотите, чтобы "B" ссылался на одно и то же. В С++ вы будете делать "typedef B A;"

К сожалению, они просто не поддерживают его. Однако, если вы контролируете все задействованные типы, вы можете нанести неприятный взлом на уровне библиотеки - вы либо расширяете B от A, либо имеете B, реализующий A.

  • 12
    Наличие typedef также было бы полезно для создания псевдонимов для вызовов универсальных типов. Например: typedef A<Long,String> B; (это может быть частный случай того, что вы описали, но он показывает привлекательность идеи немного более четко).
  • 0
    В моем случае я хочу дать псевдонимы примитивным типам. real_t для double и bool для boolean .
0

Как уже отмечалось в других ответах, вы должны избегать псевдо-typedef antipattern. Тем не менее, typedefs по-прежнему полезны, даже если это не способ их достижения. Вы хотите различать разные абстрактные типы, которые имеют одно и то же представление Java. Вы не хотите смешивать строки, которые являются паролями, с теми, которые являются уличными адресами, или целыми числами, которые представляют смещение с теми, у которых есть абсолютные значения.

Checker Framework позволяет вам определить typedef в обратном совместимости. Я работаю даже для примитивных классов, таких как int и конечных классов, таких как String. Он не имеет накладных расходов во время выполнения и не нарушает тесты на равенство.

Раздел Введите псевдонимы и typedefs в руководстве Checker Framework описано несколько способов создания typedefs в зависимости от ваших потребностей.

0

В некоторых случаях обязательная аннотация может быть только тем, что вы ищете:

https://github.com/google/guice/wiki/BindingAnnotations

Или, если вы не хотите зависеть от Guice, может быть просто обычная аннотация.

0

Возможно, это может быть другой возможной заменой:

@Data
public class MyMap {
    @Delegate //lombok
    private HashMap<String, String> value;
}
  • 2
    Не думаете ли вы, что в этом сейчас есть проблема, потому что всякий раз, когда вы определяете экземпляр myMap типа MyMap , вы можете работать с фактическим HashMap, только набрав myMapInstance.value.SomeOperation() вместо myMapInstance.SomeOperation() . Это раздражает, не так ли?
  • 0
    вы все еще можете сделать myMapInstance.SomeOperation () - это то, для чего @Delegate
0

Как уже упоминалось ранее,
В Java нет механизма typedef.
Я также не поддерживаю "поддельные классы" вообще, но здесь не должно быть строгого эмпирического правила:
Если ваш код, например, использует многократно и более "общий тип", например:

Map<String, List<Integer>> 

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

//@Alias Map<String, List<Integer>>  NameToNumbers;

И затем используйте в своем коде NameToNumbers и задайте задачу перед компилятором (ANT/Gradle/Maven) для обработки и создания соответствующего Java-кода.
Я знаю, что некоторым из читателей этого ответа может показаться странным, но это то, сколько фреймворков реализовало "аннотации" до JDK 5, вот какой проект lombok делает и другие фреймворки.

-6

Вы можете использовать Enum, хотя это семантически немного отличается от typedef, поскольку оно допускает только ограниченный набор значений. Другим возможным решением является именованный класс-оболочка, например

public class Apple {
      public Apple(Integer i){this.i=i; }
}

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

-7

Typedef позволяет элементам неявно назначать типы, которыми они не являются. Некоторые люди пытаются обойти это с помощью расширений; читайте здесь, в IBM, для объяснения, почему это плохая идея.

Изменить: в то время как вывод о сильном типе - полезная вещь, я не думаю (и надеюсь, что мы не будем) видеть typedef, воспитывая ее уродливую голову на управляемых языках (когда-либо?).

Изменить 2: В С# вы можете использовать оператор using, подобный этому, в верхней части исходного файла. Он используется, поэтому вам не нужно делать второй отображаемый элемент. Единственный раз, когда вы видите изменение имени, - это когда область вводит столкновение имен между двумя типами. Переименование ограничено одним файлом, за пределами которого каждый используемый тип переменной/параметра известен по его полному имени.

using Path = System.IO.Path;
using System.IO;
  • 22
    «Typedef позволяет неявно присваивать элементам типы, которыми они не являются» Что? Typedef просто позволяет вам создать другое имя в качестве псевдонима для типа. Тип все тот же, вы просто получите более короткое имя. Это не имеет никакого отношения к выводу типа. -1
  • 0
    @jalf: На самом деле, вывод типа используется как решение именно того, о чем вы говорите, но я привел еще один пример, где вы можете использовать «typedef», чтобы обойти конфликт имен.
Показать ещё 3 комментария
-13

В Java нет необходимости в typedef. Все это объект, за исключением примитивов. Нет указателей, только ссылок. Сценарии, в которых вы обычно используете typedefs, являются экземплярами, в которых вы создаете объекты вместо этого.

  • 18
    Нет, потребность в typedef все еще существует, если вы хотите более короткое имя для типа. Или просто, если вы хотите иметь возможность заменить использование одного типа другим, изменив одно место в исходном коде.
  • 1
    Последнее препятствует удобочитаемости, так как новому программисту придется искать определения всех типов. ОО путь - использовать вместо этого полиморфизм. Исходный код использует суперкласс или абстрактный класс / интерфейс, и конкретный тип изменяется только при создании объекта.
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню