В этой статье анализируются различия между JDK1.4, JDK1.5 и JDK1.6 в программировании Java в сочетании с примерами. Поделитесь этим для вашей ссылки, следующим образом:
Проще говоря: есть два самых больших различия между 1,4 и 1,5. Одним из них является то, что 1.5 имеет дженерики, а другой 1.5 может автоматически инкапсулировать инкапсулированные типы данных из восьми основных типов данных. То есть целое число a = 4 не допускается. Нет большой разницы между 1,5 и 1,6. 1.6 Я думаю, что большинство изменений - это графический интерфейс, который обеспечивает много удобного управления макетами и расширения.
В течение этого периода я присоединился к компании электронного правительства и использовал weblogic8. Тогда давайте использовать JDK1.4. Eclipse изменил версию JDK. Тем не менее, предыдущие проекты в основном стали популярными.
★ Новые функции JDK1.5:
1. дженерики
2 Автоматическая упаковка/распаковка
3 за все
4 Статический импорт
5 параметров переменной длины
1. Generics (избегайте запуска ошибок, которые могут быть вызваны литьем типа)
Например:
ArrayList List = new ArrayList (); list.add (новое целое число (3)); list.add (новое целое число (4)); int i = ((Integer) (list.get (0)). Parseint ();
Очень хлопотно
ArrayList <Integer> list = new ArrayList <Integer> (); list.add (новое целое число (3)); list.add (новое целое число (4)); int i = list.get (0) .parseint ();
2 Автоматическая упаковка/распаковка
Последнее предложение приведенного выше примера можно изменить на:
Кода кода следующая: int i = list.get (0);
Поскольку исходный тип и соответствующий класс обертки не должны быть явно преобразованы
3 за все
Улучшение петли
int a [] = {......}; // Инициализировать для (int i: a) {......}Не используйте предыдущий i = 0; i <A.Length; i ++
4 Статический импорт
Ранее настроенный java.math
Кода кода выглядит следующим образом: math.sqrt ();
Теперь статический импорт java.lang.math.sqrt;
sqrt ();
Это эквивалентно наличию этого метода в вашем собственном классе
5 параметров переменной длины
int sum (int ... intlist) {int sum; sum = 0; for (int i = 0; i <intlist.length; i ++) {sum+= intlist [i]; } return sum;}Есть какой -нибудь параметр, рассматривать его как массив
★ Новые функции JDK6.0
Увеличение для аннотации оператора цикла перечисления «скрытых» параметров статического метода (Vararg)
Усиление подстановочных знаков и ковариации повышены для заявлений о циклах
Для итерации над наборами и массивами, расширенный для цикла обеспечивает простой, совместимый синтаксис. Есть два момента, которые стоит упомянуть:
1. В цикле выражение инициализации рассчитывается только один раз. int выражение
Unenhanched для:
int sum = 0; Integer [] numbers = computenumbers (); for (int i = 0; i <natfy.length; i ++) sum+= числа [i];
Повышен для:
int sum = 0; для (int number: computenumbers ()) sum += число;
ограничение
Итератор или индекс не могут быть доступны во время улучшения для итерации петли
Пожалуйста, смотрите следующий пример:
for (int i = 0; i <number.length; i ++) {if (i! = 0) System.out.print (","); System.out.print (numbers [i]);}Вот еще один пример:
for (iterator <Integer> it = n.iterator (); it.hasnext ();) if (it.next () <0) it.remove ();
Комментарии
Обработка комментариев - большая тема. Поскольку эта статья фокусируется только на основных языковых функциях, мы не собираемся охватывать все его возможные формы и подводные камни. Мы обсудим встроенные аннотации (Suppresswarnings, устаревшие и переопределения) и ограничения общей обработки аннотаций.
Подавить предупреждения
Этот комментарий отключает предупреждения компилятора на уровне класса или метода. Иногда вы знаете более четко, чем компилятор, что код должен использовать отклоненный метод или выполнить какое-то действие, которое не может определить, является ли тип-защитника, и используйте:
@Suppresswarnings ("omemercation") public static void selfdestruct () {thread.currentThread (). Stop ();}Это, наверное, самая полезная вещь о встроенных аннотациях. К сожалению, Javac для 1.5.0_04 не поддерживает его. Но 1.6 поддерживает его, и Sun работает над переносом его назад на 1,5.
Эта аннотация поддерживается в Eclipse 3.1, и другие IDE могут также поддерживать его. Это позволяет полностью освободить код из предупреждения. Если есть предупреждение во время компиляции, вы можете быть уверены, что только что добавили его - чтобы помочь просмотреть код, который может быть небезопасным. С добавлением дженериков это будет удобнее использовать.
Устарел
К сожалению, устаревший не так полезен. Первоначально он был предназначен для замены тега @deprecated javadoc, но, поскольку он не содержит никаких полей, нет никакого способа предположить, что пользователи устаревших классов или методов должны использовать в качестве замены. большинство
Оба использования требует метки Javadoc и этой аннотации.
Переопределять
Переопределение говорит, что метод, который он аннотирует, должен переопределить методы с той же подписью в SuperClass:
@OverridePublic int hashcode () {...}Глядя на приведенный выше пример, если «C» не будет капитален в хэшкоде, не будет никаких ошибок во время компиляции, но метод не будет вызоваться, как и ожидалось во время выполнения. Добавив тег переопределения, компилятор запрашивает, если он фактически выполнит переписывание.
Это также полезно в ситуациях, когда суперклассы меняются. Если к методу добавляется новый параметр, а сам метод переименован, подкласс внезапно не будет составлен, потому что он больше ничего не переписывает из суперкласса.
Другие примечания
Комментарии очень полезны в других сценариях. Когда это не для того, чтобы изменить поведение напрямую, а улучшать поведение, особенно при добавлении кода шаблона, аннотация очень хорошо работает в таких структурах, как EJB и веб -сервисы.
Комментарии не могут быть использованы в качестве препроцессоров. Солнечный дизайн специально предотвращает модификацию байт -кода класса, полностью из -за комментариев. Это позволяет правильно понять результаты языка, и такие инструменты, как IDE, также могут выполнять углубленный анализ и рефакторинг.
Комментарий не серебряная пуля. Когда я впервые столкнулся с этим, люди пытались попробовать различные методы. Пожалуйста, смотрите следующие предложения, полученные от других:
открытый класс foo {@propertyprivate int bar;}Идея состоит в том, чтобы автоматически создать методы Getter и Setter для частной стержни. К сожалению, в этой идее есть два неудачи: 1) она не работает, и 2) это затрудняет чтение и обработку кода. Это невозможно реализовать, поскольку, как упоминалось ранее, Sun специально предотвращает модификацию классов с комментариями.
Даже если это возможно, это не очень хорошая идея, потому что он делает код плохо читабельным. В первый раз, когда вы видите этот код, вы не узнаете, что комментарий создает метод. Кроме того, если вам нужно выполнить некоторые операции в этих методах в будущем, комментарии бесполезны. Короче говоря, не пытайтесь делать то, что обычный код может сделать с комментариями.
перечислять
Enum очень похож на публичную статическую окончательную декларацию Int, которая использовалась в качестве значения Enum в течение многих лет. Самым большим и наиболее очевидным улучшением Int является безопасность типа - вы не можете ошибочно заменить другой тип одним типом перечисления, который отличается от INT, и все INT одинаковы для компилятора. За очень немногими исключениями, все int-структуры в стиле Enum обычно следует заменять на экземпляры.
Перечисление предоставляет некоторые дополнительные функции. Два практических класса Enummap и перечисление являются стандартными реализациями, специально оптимизированными для перечисления. Если вы знаете, что коллекция содержит только типы перечисления, вам следует использовать эти специальные коллекции вместо хэшмапа или хэшса.
В большинстве случаев вы можете использовать enum для замены всех публичных статических окончательных окончательных окончательных окончательных окончательных целей в коде. Они сопоставимы и могут быть импортированы статически, поэтому ссылки на них кажутся эквивалентными, даже для внутренних классов (или типов внутренних перечислений). Обратите внимание, что при сравнении типов перечисления инструкции, которые их объявляют, указывают на их последовательные значения.
«Скрытый» статический метод
Два статических метода появляются во всех объявлениях типа перечисления. Поскольку они являются статическими методами на подклассах Enum, а не методах самого перечисления, они не появляются в javadoc of java.lang.enum.
Первый - это значения (), который возвращает массив из всех возможных значений типа перечисления.
Второе - это значение (), которое возвращает тип перечисления для предоставленной строки, которая должна точно соответствовать объявлению исходного кода.
метод
Одним из наших любимых аспектов перечисленных типов является то, что он может иметь методы. В прошлом вам, возможно, придется написать какой -то код для преобразования публичного статического окончательного финала и преобразовать его из типа базы данных в URL JDBC. Теперь сам тип перечисления может быть сделан с полным
Методы манипулирования кодом. Вот пример, включая абстрактный метод типа перечисления базы данных и реализация, представленная в каждом экземпляре Enum:
public enum databasetype {oracle {public String getJdbcurl () {...}}, mySQL {public String getJdbcurl () {...}}; public абстрактная строка getJdbcurl ();}Теперь тип перечисления может напрямую обеспечить свои практические методы. Например:
Databasetype dbtype = ...; String jdbcurl = dbtype.getjdbcurl ();
Чтобы получить URL, вы должны заранее знать, где находится метод утилиты.
Варарг
Использование изменяющихся параметров правильно очищает код нежелания. Типичным примером является метод журнала с переменным количеством параметров строк:
Log.log (String Code) log.log (String Code, String arg) log.log (String Code, String Arg1, String Arg2) log.log (String Code, String [] args)
При обсуждении параметров переменных интересно, что если вы замените первые четыре примера на новые переменные параметры, это будет совместимо:
Скопируйте код следующим образом: log.log (String Code, String ... Args)
Все изменчивые параметры совместимы с источником, то есть, если все вызовые программы метода log () перекомпилированы, все четыре метода могут быть заменены напрямую. Однако, если требуется обратная бинарная совместимость, необходимо отбросить первые три метода. Только последний метод с параметром строкового массива эквивалентен вариальной версии, поэтому он может быть заменен вариальной версией.
Тип актерского состава
Если вы хотите, чтобы абонент знал, какой тип параметров следует использовать, вам следует избегать литья типа с изменчивыми параметрами. Глядя на следующий пример, первая надежда - строка, а вторая надежда - исключение:
Log.log (object ... Objects) {String message = (String) Objects [0]; if (objects.length> 1) {Exception e = (Exception) Objects [1]; // Сделайте что -нибудь с исключением}} Подпись метода должна быть следующей, а соответствующие изменяемые параметры объявляются с использованием строки и исключительно:
Копия кода следующим образом: log.log (строковое сообщение, Exception E, Object ... Objects) {...}
Не используйте переменные параметры для уничтожения системы типа. Это может быть использовано только тогда, когда он сильно набран. Для этого правила PrintStream.printf () является интересным исключением: оно предоставляет информацию типа в качестве своего первого аргумента, чтобы эти типы могли быть приняты позже.
Ковариация возвращается
Основное использование ковариатного возврата состоит в том, чтобы избежать литья типов, когда известно, что тип возврата реализации более конкретен, чем API. В следующем примере есть интерфейс зоопарка, который возвращает объект животного. Наша реализация возвращает объект AnimalImpl, но до JDK 1.5 он должен быть объявлен вернуть объект животного. :
Общественный интерфейс Zoo {public Animal getAnimal ();} открытый класс Zooimpl реализует Zoo {public Animal getAnimal () {return nemberimpl ();}}Использование ковариантных возвратов заменяет три анти-паттерна:
Прямой доступ Чтобы обойти ограничения API, некоторые реализации разоблачают подклассы непосредственно на поля:
Скопируйте код следующим образом: Zooimpl._animal
Другая форма состоит в том, чтобы выполнить конверсию в вызовной программе, зная, что реализация на самом деле является конкретным подклассом:
Кода -копия выглядит следующим образом: ((AnimalImpl) Zooimpl.getAnimal ()). Implmethod ();
Последняя форма, которую я видел, - это конкретный метод, который используется, чтобы избежать проблем, вызванных совершенно другой подписью:
Кода кода выглядит следующим образом: Zooimpl._getAnimal ();
Эти три режима имеют свои проблемы и ограничения. Либо это недостаточно аккуратно, либо раскрывает ненужные детали реализации.
Ковариация
Ковариантный режим возврата чище, безопаснее и прост в обслуживании, и он не требует типового литья или конкретных методов или полей:
public AnimalImpl getAnimal () {return new AnimalImpl (); } Используйте результаты:
Кода -копия выглядит следующим образом: Zooimpl.getAnimal (). Implmethod ();
Используя дженерики
Мы узнаем о дженеках с двух точек зрения: использование дженериков и построение дженериков. Мы не обсуждаем очевидное использование списка, установки и карты. Достаточно знать, что общие коллекции являются мощными и их следует использовать.
Мы обсудим использование общих методов и метод вывода компилятора. Обычно ничто из этого не пойдет не так, но когда что -то пойдет не так, сообщение об ошибке может быть очень запутанным, поэтому вам нужно знать, как решить эти проблемы.
Общие методы
В дополнение к общим типам Java 5 также вводит общие методы. В этом примере из java.util.collections построен один список элементов. Тип элемента нового списка выведен на основе типа объекта, передаваемого в методе:
Скопируйте код следующим образом: Static <t> list <t> collections.singletonlist (t o)
Пример использования:
Общественный список <Integer> getListofone () {return Collections.singletonlist (1);}В примере использования мы передаем Int. Таким образом, тип возврата метода - список <Integer>. Компилятор делает T в целое число. Это отличается от общих типов, потому что вам обычно не нужно указывать параметры типа явно.
Это также показывает взаимодействие между автобоксингом и дженериками. Параметр типа должен быть ссылочным типом: поэтому мы получаем список <Integer> вместо списка <int>.
Общие методы без параметров
Метод pellylist () введен с дженериками в виде типовой перестановки поля umpty_list в java.util.collections:
Скопируйте код следующим образом: static <t> list <t> collections.emptylist ()
Пример использования:
Общественный список <integer> getNointegers () {return collections.emptylist ();}В отличие от предыдущего примера, этот метод не имеет параметров, так как компилятор выводит тип T? По сути, он попытается использовать параметр один раз. Если это не работает, он пытается снова использовать тип возврата или назначения. В этом примере возврат - список <Integer>, поэтому T выведен как целое число.
Что произойдет, если общий метод вызывает за пределами оператора возврата или оператора назначения? Тогда компилятор не сможет выполнить вторую передачу вывода типа. В следующем примере uptyList () вызывается изнутри условного оператора:
Общественный список <Integer> getNointegers () {return x? Collections.emptylist (): null;} Поскольку компилятор не может видеть контекст возврата и не может сделать вывод, он отказывается и принимает объект. Вы увидите сообщение об ошибке, подобное: «Не удается преобразовать список <object> для списка <Integer>». »
Чтобы исправить эту ошибку, введите параметры, которые должны быть явно переданы в вызов метода. Таким образом, компилятор не будет пытаться вывести параметры типа и может получить правильный результат:
Кода -код следующим образом: return x? Коллекции. <Integer> emptylist (): null;
Другое место, где это происходит, часто находится в вызовах методов. Если метод принимает параметр <String> и необходимо вызовать пропущенный emptyList () для этого параметра, то также требуется этот синтаксис.
За пределами коллекции
Вот три примера общих типов, которые не являются коллекциями, но используют дженерики новым способом. Все три примера поступают из стандартных библиотек Java:
Скопируйте код следующим образом: класс <T>
Класс параметризован на типе класса. Это позволяет построить новичок без листа типа.
Скопируйте код следующим образом: сопоставимо <T>
Сопоставимый параметризован фактическим типом сравнения. Это обеспечивает более сильную набор при вызовах сравнения (). Например, строка реализует сопоставимые <string>. Вызов CompareTo () на что -либо, кроме строки, потерпит неудачу во время компиляции.
Скопируйте код следующим образом: enum <E Extends enum <e>>
Enum параметризован типом перечисления. Тип enum с именованным цветом расширит enum <folue>. Метод getDeclaringClass () возвращает объект класса типа перечисления, в этом примере цветовой объект. Это отличается от getClass (), который может вернуть безымянный класс.
Подстановочный знак
Наиболее сложной частью генериков является понимание персонажей подстановочных знаков. Мы обсудим три типа подстановки и их использование.
Сначала давайте поймем, как работают массивы. Вы можете присвоить значение из целого числа [] к числу []. Если вы попытаетесь написать поплавок по номеру [], его можно скомпилировать, но оно не будет проходить во время выполнения, и появится ArraystoreException:
Целое число [] ia = новое целое число [5]; число [] na = ia; na [0] = 0,5; // компилируется, но не удается во время выполнения
Если вы попытаетесь преобразовать пример непосредственно в универсальный, он потерпит неудачу во время компиляции, потому что назначение не разрешено:
List <Integer> ilist = new ArrayList <Integer> (); List <Cumber> nlist = ilist; // не допускается allist.add (0,5);
Если вы используете Generics, вы не встретите время выполнения ClassCastException, пока код не появляется при компиляции.
Верхний предел подстановки
Что мы хотим, так это список неизвестного точного типа элемента, который отличается от массивов.
Список <число> - список, тип элемента которого является конкретным номером типа.
Список <? Extends Number> - список точного типа элемента неизвестен. Это число или его подтип.
Верхний предел
Если мы обновим начальный пример и присвоили значение списку <? расширяет номер>, тогда назначение будет успешным сейчас:
Список <integer> ilist = new ArrayList <Integer> (); List <? Extends Number> nlist = ilist; число n = nlist.get (0); nlist.add (0,5); // не разрешен
Мы можем получить номер из списка, потому что мы можем назначить его номеру независимо от точного типа элемента списка (Float, Integer или Number).
Мы все еще не можем вставить типы плавучих точек в список. Это потерпит неудачу во время компиляции, потому что мы не можем доказать, что это безопасно. Если мы хотим добавить в список типов с плавающей запятой, он сломает безопасность начального типа ILIST - он хранит только целое число.
Укриста дают нам более выразительную силу, чем массивы.
Зачем использовать подстановочные знаки
В следующем примере подстановки используются для скрытия информации типа от пользователей API. Внутренне, набор хранится как CustomerImpl. Пользователи API знают, что они получают набор, из которого они могут читать клиента.
Здесь требуются подстановочные знаки, потому что невозможно назначить значения для SET <Customer> из SET <CustomerImpl>:
открытый класс customerfactory {private Set <CustomerImpl> _customers; public set <? Extends Customer> getCustomers () {return _customers;}}Подстановочный знак и ковариант
Еще одно распространенное использование персонажей подстановочных знаков - использовать его с ковариантом. Те же правила, что и уступка, могут быть применены к ковариантным возвратам. Если вы хотите вернуть более конкретный общий тип в переписанном методе, объявленный метод должен использовать подстановочный знак:
Общественный номер интерфейса Generator {public list <? extends №> Generate ();} открытый класс Fibonaccigerator Extends NumberGenerator {public List <Integer> Generate () {...}}Если вы хотите использовать массив, интерфейс может вернуть номер [], в то время как реализация может вернуть целое число [].
Нижний предел
То, о чем мы говорим, в основном о подстановочном значении верхнего предела. Существует также нижний предел подстановочного знака. Список <? Super Number> - это список точного «типа элемента» неизвестен, но это может быть Mnumber, или супертип числа. Так что это может быть список <номер> или список <object>.
Нижняя подстановка гораздо реже, чем подстановочные знаки, но они необходимы, когда они необходимы.
Нижний и верхний предел
Список <? extends №> readlist = new ArrayList <Integer> (); номер n = readlist.get (0); list <? Super Number> writelist = new ArrayList <object> (); writelist.add (новое целое число (5));
Первый - это список чисел, которые можно прочитать.
Второй - это список номеров, на которые вы можете написать.
Неограниченный подстановочный знак
Наконец, содержание списка <?> Может быть любого типа, и он почти такой же, как и список <? расширяет объект>. Объекты могут быть прочитаны в любое время, но контент не может быть записан в список.
Подстановочные знаки в общественных API
Короче говоря, как упоминалось ранее, подстановочные знаки очень важны для сокрытия деталей реализации от вызывающего абонента, но даже если нижние границы, по-видимому, обеспечивают доступ только для чтения, они не являются случайными из-за негенерических методов, таких как relement (Int Position). Если вы хотите по -настоящему неизменную коллекцию, вы можете использовать метод на java.util.collection, например, unmodifiablelist ().
Помните подстановочные знаки при написании API. Как правило, при прохождении общих типов вы должны попробовать использовать подстановочные знаки. Это позволяет большему количеству вызывающих абонентов получить доступ к API.
Получив список <? Extends Number> Вместо списка <номер> можно вызвать следующим методом множеством различных типов списков:
Кода кода следующая: void Removenegatives (List <? Extends Number> List);
Построить общие типы
Теперь мы обсудим построение наших собственных общих типов. Мы покажем некоторые примеры, где безопасность типа может быть улучшена с помощью Generics, и мы также обсудим некоторые общие проблемы при внедрении общих типов.
Коллекционные функции
Первым примером общего класса является пример стиля сбора. Пара имеет два параметра типа, а поле является экземпляром типа:
Public Final Class Pare <A, B> {Public Final A First; Public Final B -Second; Public Pair (A First, B Second) {this.first = First; this.second = second;}}Это позволяет вернуть два элемента из метода, не написав выделенный класс для каждой комбинации двух типов. Другой способ - вернуть объект [], который является типом небезопасно или неопрятного.
В следующем использовании мы возвращаем файл и логический из метода. Клиент метода может использовать поля непосредственно без литья типа:
public pair <file, boolean> getFileAndWriteStatus (String Path) {// Создать файл и новую пару File и Statesturn <File, boolean> (file, status);} pair <file, boolean> result = getFileAndWritestatus ("..."); файл f = result.first; логический писатель = result.second;За пределами коллекции
В следующем примере генерики используются для дополнительной безопасности. Параметризуя класс DBFactory в созданный тип сверстников, вы фактически вынуждаете заводский подкласс вернуть конкретный подтип однорангового языка:
Общедоступный абстрактный класс dbfactory <t Extends dbpeer> {Защищенный абстрактный t createMptypeer (); public list <t> get (строка ограничения) {list <t> peers = new ArrayList <t> (); // база данных MagicRen Peers;}}}}}}}}}}}Внедряя dbfactory <Customer>, CustomerFactory должен вернуть клиента из CreateMptyPeer ():
Public Class CustomerFactory Extends dbFactory <Customer> {public customer createMptypeer () {return new Customer ();}}Общие методы
Независимо от того, хотите ли вы наложить ограничения на общие типы между параметрами и между параметрами и типами возврата, вы можете использовать общие методы:
Например, если записанная функция инверсии инвертируется позиционно, то общий метод может не потребоваться. Однако, если вы хотите, чтобы инверсия вернула новый список, вы можете понадобиться, чтобы тип элемента нового списка был таким же, как тип входящего списка. В этом случае необходим общий метод:
Скопируйте код следующим образом: <T> List <t> Reverse (List <T> List)
Конкретный
При внедрении общего класса вы можете построить массив T []. Поскольку дженерики реализованы с помощью стирания, это не разрешено.
Вы можете попробовать лить объект [] to []. Но это не безопасно.
Бетонные решения
Согласно соглашению об общих уроках, решение использует «токен типа». Добавив параметр класса <T> в конструктор, вы можете заставить клиента предоставить правильный объект класса для параметров типа класса:
открытый класс ArrayExample <t> {private class <t> clazz; public arrayExample (class <t> clazz) {this.clazz = clazz;} public t [] getarray (int size) {return (t []) array.newinstance (clazz, size);}}Чтобы построить ArrayExample <string>, клиент должен передать string.class в конструктор, потому что тип string.class - это класс <string>.
Наличие объекта класса позволяет построить группу правильного типа элемента
Я надеюсь, что эта статья будет полезна для всех Java Programming.