Пакеты, исключения, дженерики
Валеев Тагир
1
, , 1 - - PowerPoint PPT Presentation
, , 1 ( , , )
1
Имя пакета Package name Имя класса верхнего уровня Top level class name Простое имя класса Simple name Полноквалифицированное имя класса Fully-qualified class name (FQN)
Имя класса в виртуальной машине JVM class name
2
✓ Располагается в каталоге x/y/z относительно корня элемента classpath ✓ Содержит заголовок “package x.y.z;” ✓ На классы из текущего пакета и из пакета java.lang можно ссылаться по простому имени. ✓ Для использования класса из другого пакета пишем его полное имя “x.y.z.ClassName” ✓ Если полное имя писать неохота, пишем в начале файла “import x.y.z.ClassName;” ✓ Для использования любых классов из пакета по простому имени, пишем “import x.y.z.*;” ✓ По умолчанию классы, поля, методы доступны из текущего пакета ✓ Пакеты “x.y.a”, “x.y.b”, “x.y” в отношениях не состоят.
3
4
✓ Пакет: полностью маленькие буквы, обратное доменное имя, принадлежащее автору или компании. ✓ Нельзя использовать пакеты java. и javax. (они используются стандартной библиотекой и защищены лиценцией). ✓ Класс: каждое слово с большой буквы. ✓ Метод: camelCase (первое слово с маленькой буквы), раньше рекомендовали начинать с глаголов. ✓ Поле, переменная: camelCase (существительное)
5
Модификатор Класс Пакет Подкласс Все желающие public Да Да Да Да protected Да Да Да Нет (package-private) Да Да Нет Нет private Да Нет Нет Нет
6
// a/AbstractGreeter.java package a; public abstract class AbstractGreeter { private final String recipient; protected AbstractGreeter(String recipient) { this.recipient = recipient; } protected void hello() { System.out.println("Hello "+ recipient +"!"); } }
7
// b/Foo.java package b; import a.AbstractGreeter; public class WorldGreeter extends AbstractGreeter { public WorldGreeter() { super("World"); } void test(AbstractGreeter other) { this.hello(); super.hello();
} }
8
9
import static java.util.Arrays.*; public class Test { public static void main(String[] args) { int[] data = {5,3,1,7,2,4,6}; sort(data); System.out.println(toString(data)); } }
10
import static java.util.Arrays.*; public class Test { public static void main(String[] args) { int[] data = {5,3,1,7,2,4,6}; sort(data); System.out.println(toString(data)); } }
11
12
13
public class Test { static class MyException extends Exception { } static void test() throws MyException { throw new MyException(); } public static void main(String[] args) { test(); } }
14
public class Test { static class MyException extends Exception { } static void test() throws MyException { throw new MyException(); } public static void main(String[] args) throws MyException { test(); } }
Throwable Exception Error
RuntimeException AssertionError ThreadDeath VirtualMachineError LinkageError
NoClassDefFoundError NoSuchFieldError NoSuchMethodError AbstractMethodError InstantiationError ClassFormatError ExceptionInInitializerError VerifyError StackOverflowError OutOfMemoryError InternalError IOException SQLException IllegalAccessException NoSuchFieldException NoSuchMethodException ClassNotFoundException InvocationTargetException TimeoutException ExecutionException NullPointerException ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException IllegalArgumentException IllegalStateException UnsupportedOperationException IndexOutOfBoundsException NoSuchElementException ConcurrentModificationException UncheckedIOException 15
16
17
18
public static void main(String[] args) { try { test(); } catch (MyException ex) { ex.printStackTrace(); } } Test$MyException at Test.test(Test.java:7) at Test.main(Test.java:12)
19
✓ Фреймворки: Log4j, Logback, Slf4j, Java Logging API (java.util.logging) ✓ Уровни (насколько всё плохо): ERROR/WARN/INFO/DEBUG ✓ Форматтеры: как логировать? (представление сообщений) ✓ Аппендеры: куда логировать?
20
21
public class PoolComposerPrincipalEventIdentifier { private static final Logger LOG = Logger.getLogger( PoolComposerPrincipalEventIdentifier.class.getName()); public void identifyPrincipalEvent() { try { doIdentifyPrincipalEventUsingPoolComposer(); } catch(Exception ex) { LOG.log(Level.SEVERE, "Error while identifying principal event", ex); } } }
https://projects.haykranen.nl/java/
22
static class MyException extends Exception { public MyException(String message) { super(message); } } void readFile() throws MyException { try { byte[] bytes = Files.readAllBytes(Paths.get("/etc/passwd")); System.out.println(Arrays.toString(bytes)); } catch (IOException e) { throw new MyException("Unable to read file"); } } Test$MyException: Unable to read file at Test.readFile(Test.java:16) at Test.main(Test.java:22)
23
static class MyException extends Exception { public MyException(String message) { super(message); } public MyException(String message, Throwable cause) { super(message, cause); } } void readFile() throws MyException { try { byte[] bytes = Files.readAllBytes(Paths.get("/etc/passwd")); System.out.println(Arrays.toString(bytes)); } catch (IOException e) { throw new MyException("Unable to read file", e); } }
24
Test$MyException: Unable to read file at Test.readFile(Test.java:16) at Test.main(Test.java:22) Caused by: java.nio.file.NoSuchFileException: \etc\passwd at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:7 at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102 at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.j at java.nio.file.Files.newByteChannel(Files.java:361) at java.nio.file.Files.newByteChannel(Files.java:407) at java.nio.file.Files.readAllBytes(Files.java:3152) at Test.readFile(Test.java:13) ... 1 more
25
https://youtu.be/_0c9Fd9FacU
26
public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapFactory) {…}
✓ Класс или интерфейс может быть объявлен обобщённым (generic, дженерик):
✓ class List<T> ✓ class Map<K, V> ✓ class NumberList<T extends Number> ✓ class X<T extends Y & Z>
✓ Здесь T, K, V – параметры типа, а сам класс задаёт параметризованный тип. ✓ Параметр типа может использоваться внутри нестатических членов класса:
✓ Тип поля, параметра, переменной ✓ Возвращаемый тип метода ✓ Подставляться параметром другого типа
✓ Для использования параметризованного типа необходимо подставить все параметры (с помощью явных непримитивных типов, других параметров типов либо маски)
27
28
/** A box which is either empty or contains a non-null value */ static class Option<T> { T value; /** Passing null means absent value */ public Option(T value) { this.value = value; } /** Never returns null */ public T get() { if(value == null) throw new NoSuchElementException(); return value; } public T orElse(T other) { return value == null ? other : value; } public boolean isPresent() { return value != null; } }
29
/** A mutable box which is either empty or contains a non-null value */ static class Shmoption<T> { T value; /** Passing null means absent value */ public Shmoption(T value) { this.value = value; } /** Never returns null */ public T get() { if(value == null) throw new NoSuchElementException(); return value; } public void set(T newValue) { value = newValue; } public T orElse(T other) { return value == null ? other : value; } public boolean isPresent() { return value != null; } }
30
Shmoption<String> present = new Shmoption<String>("yes"); Shmoption<String> absent = new Shmoption<String>(null); System.out.println(present.isPresent()); System.out.println(present.get()); System.out.println(absent.isPresent()); System.out.println(absent.orElse("no"));
31
Shmoption<String> present = new Shmoption<String>("yes"); Shmoption<String> absent = new Shmoption<String>(null); System.out.println(present.isPresent()); System.out.println(present.get()); System.out.println(absent.isPresent()); System.out.println(absent.orElse("no"));
(“?” = “? extends Object”)
32
Shmoption<?> present = new Shmoption<>("yes"); System.out.println(present.isPresent()); System.out.println(present.get()); Use-site variance (вариативность в точке использования)
(“?” = “? extends Object”)
33
Shmoption<?> present = new Shmoption<>("yes"); System.out.println(present.isPresent()); Object value = present.get(); System.out.println(value); present.set(???);
(“?” = “? extends Object”)
34
Shmoption<?> present = new Shmoption<>("yes"); System.out.println(present.isPresent()); Object value = present.get(); System.out.println(value); present.set(???);
35
Shmoption<?> present = new Shmoption<>("yes"); System.out.println(present.isPresent()); Object value = present.get(); System.out.println(value); present.set(null);
36
Shmoption<Object> present = new Shmoption<>("yes"); System.out.println(present.isPresent()); Object value = present.get(); System.out.println(value); present.set(123);
37
Shmoption<? extends Number> number = new Shmoption<>(123); Number n = number.get(); number.set(124);
38
class NumberShmoption<N extends Number> extends Shmoption<N> { public NumberShmoption(N value) { super(value); } } class IntegerShmoption extends NumberShmoption<Integer> { public IntegerShmoption(Integer value) { super(value); } }
39
NumberShmoption<?> number = new NumberShmoption<>(123); Number n = number.get(); number.set(124); IntegerShmoption integer = new IntegerShmoption(123); Integer i = integer.get(); integer.set(124); number = integer;
40
41
42
IntegerShmoption NumberShmoption<?> Shmoption<?> Shmoption<Double> Shmoption<? extends Number> Shmoption<? super Number> NumberShmoption<Integer> Shmoption<Integer> Shmoption<Number> Shmoption<Object> NumberShmoption<Double>
43
static double getDoubleValue(Shmoption<Number> shmopt) { return shmopt.get().doubleValue(); } getDoubleValue(new IntegerShmoption(123));
44
static double getDoubleValue(Shmoption<? extends Number> shmopt) { return shmopt.get().doubleValue(); } getDoubleValue(new IntegerShmoption(123));
45
static void setInteger(Shmoption<Integer> shmopt) { shmopt.set(42); } NumberShmoption<Number> n = new NumberShmoption<>(123.45); setInteger(n);
46
static void setInteger(Shmoption<? super Integer> shmopt) { shmopt.set(42); } NumberShmoption<Number> n = new NumberShmoption<>(123.45); setInteger(n);
Producer – extends (covariance) Consumer – super (contravariance)
47
Picture courtesy : Andrey Tyukin https://stackoverflow.com/a/19739576/4856258
48
interface Supplier { Object get(); } interface StringSupplier extends Supplier { @Override String get(); }
49
static <T> void setNotNull(Shmoption<? super T> shmoption, T value) { if (value == null) throw new IllegalArgumentException(); shmoption.set(value); } setNotNull(n, 123); ShmoptionUtils.<Number>setNotNull(n, 123);
50
✓ Не все типы известны во время выполнения ✓ В частности, значения параметров типов «стёрты» ✓ Преобразование типов не всегда бывает безопасным (checked) ✓ Если оно небезопасно, вы получите unchecked cast warning ✓ При выполнении это может привести к проблемам (ClassCastException) в дальнейшем ✓ Программа считается безопасной с точки зрения системы типов, если типы выражений в рантайме соответствуют типам во время компиляции (ClassCastException происходит только при явном преобразовании типа). ✓ Если предупреждений нет, то программа безопасна *
* На самом деле нет: Java and Scala’s Type Systems are Unsound https://github.com/namin/unsound/blob/master/doc/unsound-oopsla16.pdf
51
Shmoption<Integer> integer = new Shmoption<>(10); Shmoption<String> string = ((Shmoption<String>) integer); // ошибка Shmoption<?> any = integer; Shmoption<String> string2 = (Shmoption<String>) any; // предупреждение String s = string2.get(); // ClassCastException NumberShmoption<Integer> number = (NumberShmoption<Integer>)integer; // нормально
52
Shmoption shmoption = new Shmoption(10); shmoption.set("foo"); Object o = shmoption.get();
✓ Нужны для совместимости с Java 1.4.2 и старше ✓ Не используйте их ✓ Не нужно искать в них логику, просто не используйте их ✓ – Доктор, когда я вот так делаю, у меня вон там болит. – Так вы не делайте так!
Дружат как кошка с собакой
53
Shmoption<?>[] array = new Shmoption<?>[10]; Shmoption<Integer>[] arrayInt = new Shmoption<Integer>[10];
Дружат как кошка с собакой
54
Shmoption<?>[] array = new Shmoption<?>[10]; Shmoption<Integer>[] arrayInt = new Shmoption<Integer>[10]; Shmoption<Integer>[] arrayInt = new Shmoption[10]; // предупреждение Object[] obj = arrayInt;
Shmoption<Integer> shmoption = arrayInt[0]; Integer x = shmoption.get(); System.out.println(x);