Как параметризовать статический метод java
Перейти к содержимому

Как параметризовать статический метод java

  • автор:

Как параметризировать статический метод java

Аватар пользователя Иван Полежаев

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

Вы можете параметризовать этот метод, передав ему в качестве аргументов два объекта типа T , где T — это обобщенный тип, как показано в следующем примере:

В этом примере мы использовали обобщенный тип <T extends Number> для параметризации метода sum() . Здесь мы ограничиваем тип T , чтобы он был типом Number или его подклассом, и таким образом мы можем использовать метод doubleValue() для преобразования значения объектов типа T в тип double

Таким образом, мы можем вызвать параметризованный статический метод sum() следующим образом:

Static parameterized methods in Java

I thought I understood generics. However, in this example, I cannot figure out why line isIn1(new Class2(1), arr); is compiled and line isIn2(new Class2(1), arr); is not compiled.

clipper1995's user avatar

2 Answers 2

prints "Not is in" because Class2.equals returns false when this and o are not instances of the exact same class:

arr contains an instance of Class1 , but you passed an instance of Class2 as the first parameter to isIn1 .

Does not compile because there is no types that satisfy the constraints you specified in isIn2 that can be inferred. Specifically, there has to be a type T that is a subtype of Comparable<T> and a type V that is a subtype of T . Class2 would also have to be compatible with T , and Class1[] would have to be compatible with V[] .

"How about T is Class2 and V is Class1 ?" you might say:

That doesn’t work because Class1 is not a subtype of Class2 . They are unrelated at all! The similar isIn1 call fails for the same reason.

By not specifying the generic type parameters, the compiler can try its best to infer the types so that the code compiles. Also note that isIn1 has one fewer constraint than isIn2 .

Here, one solution is T is Comparable<? extends Comparable<?>> , and V is Class1 .

You can check that they satisfy the constraints by using the sub typing rules described in Section 4.10 of the JLS.

Как параметризовать статический метод java

Аватар пользователя Иван Полежаев

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

Вы можете параметризовать этот метод, передав ему в качестве аргументов два объекта типа T , где T — это обобщенный тип, как показано в следующем примере:

В этом примере мы использовали обобщенный тип <T extends Number> для параметризации метода sum() . Здесь мы ограничиваем тип T , чтобы он был типом Number или его подклассом, и таким образом мы можем использовать метод doubleValue() для преобразования значения объектов типа T в тип double

Таким образом, мы можем вызвать параметризованный статический метод sum() следующим образом:

Статические методы и поля. Модификатор native. Модификатор synchronized. Логические блоки.

Поля данных, объявленные в классе как static, являются общими для всех объектов класса и называются переменными класса. Если один объект изменит значение такого поля, то это изменение увидят все объекты.

Вызов статического метода также следует осуществлять с помощью указания: ClassName.methodName().

Приложение на языке Java может вызывать методы, написанные на языке С++. Такие методы объявляются с ключевым словом native, которое сообщает компи- лятору, что метод реализован в другом месте. Например: public native int loadCripto(int num); Методы, помеченные native, можно переопределять обычными методами в подклассах.

При использовании нескольких потоков управления в одном приложении необходимо синхронизировать методы, обращающиеся к общим данным. Когда интерпретатор обнаруживает synchronized, он включает код, блокирующий доступ к данным при запуске потока и снимающий блок при его завершении. Вызов методов уведомления о возвращении блокировки объекта notifyAll(), notify() и метода остановки потока wait() класса Object (суперкласса для всех классов языка Java) предполагает использование модифи- катора synchronized, так как эти методы предназначены для работы с пото- ками.

При описании класса могут быть использованы логические блоки. Логиче- ским блоком называется код, заключенный в фигурные скобки и не принадлежа- щий ни одному методу текущего класса, например: static При создании объекта класса они вызываются последовательно, в порядке разме- щения, вместе с инициализацией полей как простая последовательность операто- ров, и только после выполнения последнего блока будет вызван конструктор класса. Операции с полями класса внутри логического блока до явного объявле- ния этого поля возможны только при использовании ссылки this, представляю- щую собой ссылку на текущий объект.

Параметризованные классы. Параметризованные методы. Методы с переменным числом параметров.

К наиболее важным новшествам версии языка J2SE 5 можно отнести появле- ние параметризованных (generic) классов и методов, позволяющих использовать более гибкую и в то же время достаточно строгую типизацию, что особенно важ- но при работе с коллекциями. Параметризация позволяет создавать классы, интерфейсы и методы, в которых тип обрабатывае- мых данных задается как параметр.

Объявление generic-типа в виде <T>, несмотря на возможность использо- вать любой тип в качестве параметра, ограничивает область применения разра- батываемого класса. Переменные такого типа могут вызывать только методы класса Object. Доступ к другим методам ограничивает компилятор, предупре- ждая возможные варианты возникновения ошибок. Чтобы расширить возможности параметризованных членов класса, можно ввести ограничения на используемые типы при помощи следующего объявления класса: public class OptionalExt <T extends Tип> Такая запись говорит о том, что в качестве типа Т разрешено применять толь- ко классы, являющиеся наследниками (суперклассами) класса Tип, и соответ- ственно появляется возможность вызова методов ограничивающих (bound) типов.

Параметризованный (generic) метод определяет базовый набор операций, ко- торые будут применяться к разным типам данных, получаемых методом в каче- стве параметра, и может быть записан, например, в виде: <T extends Тип> returnType methodName(T arg) <> <T> returnType methodName(T arg) <> Описание типа должно находиться перед возвращаемым типом. Запись пер- вого вида означает, что в метод можно передавать объекты, типы которых явля- ются подклассами класса, указанного после extends. Второй способ объявления метода никаких ограничений на передаваемый тип не ставит. Generic-методы могут находиться как в параметризованных классах, так и в обычных. Параметр метода может не иметь никакого отношения к параметру сво- его класса.

Возможность передачи в метод нефиксированного числа параметров позволя- ет отказаться от предварительного создания массива объектов для его последую- щей передачи в метод.

public class DemoVarargs

Типобезопасные перечисления (typesafe enums) в Java представляют собой классы и являются подклассами абстрактного класса java.lang.Enum. При этом объекты перечисления инициализируются прямым объявлением без помощи оператора new. При инициализации хотя бы одного перечисления происходит инициализация всех без исключения оставшихся элементов данного перечисления.

Перечисление как подкласс класса Enum может содержать поля, конструкто- ры и методы, реализовывать интерфейсы. Каждый тип enum может использо- вать методы: static enumType[] values() – возвращает массив, содержащий все элементы перечисления в порядке их объявления; static T valueOf(Class<T> enumType, String arg) – возвра- щает элемент перечисления, соответствующий передаваемому типу и значению передаваемой строки; static enumType valueOf(String arg) – возвращает элемент пере- числения, соответствующий значению передаваемой строки; int ordinal() – возвращает позицию элемента перечисления.

Static parameterized methods in Java

I thought I understood generics. However, in this example, I cannot figure out why line isIn1(new Class2(1), arr); is compiled and line isIn2(new Class2(1), arr); is not compiled.

clipper1995's user avatar

2 Answers 2

prints "Not is in" because Class2.equals returns false when this and o are not instances of the exact same class:

arr contains an instance of Class1 , but you passed an instance of Class2 as the first parameter to isIn1 .

Does not compile because there is no types that satisfy the constraints you specified in isIn2 that can be inferred. Specifically, there has to be a type T that is a subtype of Comparable<T> and a type V that is a subtype of T . Class2 would also have to be compatible with T , and Class1[] would have to be compatible with V[] .

"How about T is Class2 and V is Class1 ?" you might say:

That doesn’t work because Class1 is not a subtype of Class2 . They are unrelated at all! The similar isIn1 call fails for the same reason.

By not specifying the generic type parameters, the compiler can try its best to infer the types so that the code compiles. Also note that isIn1 has one fewer constraint than isIn2 .

Here, one solution is T is Comparable<? extends Comparable<?>> , and V is Class1 .

You can check that they satisfy the constraints by using the sub typing rules described in Section 4.10 of the JLS.

Русские Блоги

Изучите параметризацию поведения Java 8 за пять минут

1. Обзор

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

До Java 8, если вы хотели использовать ядра нескольких компьютеров, вам приходилось использовать потоки и иметь дело со сложной логикой синхронизации. Но в Java 8 вы можете легко использовать потоки, чтобы ваш код выполнялся на нескольких ядрах.

Кроме того, он также использует содержимое других языков и библиотек с открытым исходным кодом, таких как Scala, Guava и т. Д. Мы резюмируем основные функции или улучшения Java 8:

  1. Функциональное программирование и лямбда-выражения;
  2. Потоковое программирование;
  3. Улучшения Time API;
  4. Метод по умолчанию

2. Параметризация поведения

«Поведение» относится к методам, а «параметризация поведения» относится к передаче методов в качестве параметров. Грубо говоря, это означаетСтратегический режим. Однако Java 8 просто использует лямбда-выражения, чтобы упростить код анонимных классов и сделать анонимные классы более лаконичными. В этом контенте не так много вещей, которые вам нужно освоить.

2.1 Базовый синтаксис лямбда-выражения

Выше приведен базовый синтаксис Lambda, первая строка — это случай использования выражений в Lambda, а вторая строка — случай использования операторов в китайской Lambda.

Вот несколько примеров использования лямбда-выражений:

Из приведенного выше примера кода мы можем подытожить некоторые выводы:

  1. Так называемый функциональный интерфейс относится к интерфейсу, который содержит только один метод не по умолчанию, который можно использовать. @FunctionalInterface Аннотация указывает, что указанный интерфейс является интерфейсом функции;
  2. Если в лямбде -> Ниже приводится инструкция, и когда она состоит только из одной строки, мы можем удалить фигурные скобки;
  3. Если вы хотите присвоить объекту лямбда-выражение, если объект не Функциональный интерфейс , Тогда IDEA выдаст подсказку;
  4. Также обратите внимание, что функциональным интерфейсам не разрешено генерировать проверенные исключения.

Ниже мы приводим некоторые примеры общих ссылок на методы:

В приведенном выше коде Employee::new Это так называемая ссылка на метод. Ниже приведены примеры общих ссылок на методы:

Нумерация Lambda Справочник по эквивалентному методу
1 (Employee e)->e.getName() Employee::getName
2 (String s) -> System.out.println(s) System.out::println
3 (str, i) -> str.substring(i) String::substring

Поэтому мы суммировали три приведенных метода:

Нумерация Lambda Справочник по эквивалентному методу
1 (Параметр) -> имя класса. Статический метод (параметр) Имя класса :: статический метод
2 (Параметр 1, другие параметры) -> параметр 1. Метод экземпляра (другие параметры) Имя класса :: метод экземпляра
3 (Параметр) -> выражение. Метод экземпляра (параметр) Выражение :: метод экземпляра
2.2 Функциональный интерфейс в Java API

API Java 8 предоставляет нам несколько функциональных интерфейсов, с которыми необходимо разбираться. Поскольку интерфейсы могут определять методы по умолчанию, начиная с Java8, в этих интерфейсах есть несколько интересных методов по умолчанию. Это может быть более полезно для нашего программирования.

Выше приведены определения этих трех интерфейсов. Разница в сценариях их применения отражается в возвращаемых параметрах:

  1. Первый используется для оценки, грубо говоря, для достижения эффекта фильтрации;
  2. Во-вторых, нет возвращаемого типа, который можно использовать только для обработки входящих параметров;
  3. Третий используется для сопоставления, то есть вы можете использовать его, когда параметры и возвращаемое поведение, которого вы хотите достичь, имеют разные типы (конечно, если они одного типа).

Поскольку для числовых типов Java требует дополнительных операций упаковки и распаковки, что требует больших затрат. Следовательно, для трех вышеуказанных интерфейсов (а также других интерфейсов) Java 8 предоставляет версию, которая не требует упаковки, то есть она изменилась с универсального типа на числовой. Возьмем, к примеру, IntPredicate:

2.3 Составное лямбда-выражение

Некоторые интерфейсы, представленные в Java 8, могут быть комбинированными операциями. Используйте составные операции для достижения более сложной логики. Эти составные операции определены в форме методов по умолчанию, и каждый функциональный интерфейс немного отличается. Поэтому мы перечислим лишь некоторые методы компаундирования. В фактическом процессе разработки вы можете напрямую войти в назначенный функциональный интерфейс, чтобы просмотреть определение этих методов.

2.3.1 Компаратор

Предположим, есть список данных «Сотрудники», где объектом является «Сотрудник», у него есть два метода: getName () и getAge ().

В двух приведенных выше строках кода первая строка реализует сортировку сотрудников в соответствии с результатом getName (). Вторая строка кода сначала сортирует сотрудников в соответствии с результатом getName (), затем меняет возвращенный результат на противоположный, а затем сортирует в соответствии с результатом getAge ().

2.3.2 Предикатное сложное отрицание (), или () и ()

Здесь сначала определяется employeePredicate, который можно использовать для фильтрации «сотрудников старше 13 лет». Вызов метода negate () вернет предикат, который можно использовать для фильтрации «служащих меньше или равных 13». Последняя составная операция означает «сотрудники, возраст которых от 13 до 15 лет, или сотрудники по имени LiHua».

Обратите внимание, что порядок операций and и or здесь слева направо, то есть a.or(b).and(c) Будет рассматриваться как (a || b) and c 。

2.3.3 Составная функция

Функция имеет два метода по умолчанию: andThen и compose, оба из которых возвращают экземпляр функции.

Вышеупомянутое является примером составной операции Function. Фактически, ее действие эквивалентно составной функции в математике. Однако следует отметить, что фактические комбинированные эффекты двух методов различаются.

подводить итоги

Вышеупомянутое является первой частью усовершенствования Java 8. Подводя итог: параметризация поведения на самом деле является стратегическим режимом. Использование Lambda может упростить форму функциональных интерфейсов; Java API предоставляет несколько полезных функциональных интерфейсов, которые могут быть более мощными при использовании составных методов. Функция.

Общие методы Java и статические фабричные методы — синтаксис

Мой вопрос действительно о синтаксисе дженериков в сочетании с методом статического factory. Я действительно не понимаю, почему мы помещаем <T> перед типом возвращаемого значения в объявлении метода. Это похоже на приведение типов? Любая помощь будет высоко оценена!

5 ответов

То, о чем вы спрашиваете, это тип inferrence.

Поскольку это статический метод, он должен где-то выводить тип Generic; У вас нет экземпляра класса. То, что означает <T> .

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

При использовании этого метода T выводится из цели (в данном случае String ):

В другом статическом методе, где у вас есть общий аргумент, T выводится из передаваемого типа:

Здесь, если вы попытались сделать:

Это скажет вам, что ваш тип цели был неправильным, и вам понадобился List<Integer>

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *