Java. Part 2 Спецификаторы доступа • • • • public private protected не указан – доступ в пределах пакета • Могут использоваться перед классами, методами, полями Инициализация …. void f() { int i; i++; //не компилируется } … Инициализация class Test { int i; public Test() { i++; System.out.println(i); } } Инициализация class Test { int n = 3; int i = foo(n); int foo(int num) { return 11*num; } } Инициализация public class StaticTest { static int i; int j, h; static { i = 25; System.out.println("Hello1"); } { j = 8; h = 3; System.out.println("Hello2"); } public static void main(String[] args) { System.out.println("Hello3"); StaticTest t = new StaticTest(); } } final • «Это нельзя изменить» • Можно использовать для данных, методов, классов • Для классов – нельзя иметь наследников • Для методов – нельзя изменить в производных классах (private => final) final поля • Константа времени компиляции • Значение инициализируемое в процессе работы, но которое нельзя изменить. (Аккуратнее со ссылками!) final public class BlankFinal { private final int i = 0; public static final int N = 10; private final int j; public BlankFinal(int x) { j = x; } } final class WithFinals { private final void f() { System.out.println("WithFinals.f()"); } private void g() { System.out.println("WithFinals.g()"); } public void foo() { f(); g(); } } class OverridingPrivate extends WithFinals { private final void f() { System.out.println("OverridingPrivate.f()"); } private void g() { System.out.println("OverridingPrivate.g()"); } } class OverridingPrivate2 extends OverridingPrivate { public final void f() { System.out.println("OverridingPrivate2.f()"); } public void g() { System.out.println("OverridingPrivate2.g()"); } } public class FinalTest { public static void main(String[] args) { OverridingPrivate2 op2 = new OverridingPrivate2(); op2.f(); op2.g(); OverridingPrivate op = op2; //! op.f(); //! op.g(); WithFinals wf = op2; //! wf.f(); //! wf.g(); op2.foo(); } } Overload vs Overriding • Overload (перегрузка) – использование одного идентификатора для ссылки на разные элементы в одной области действия. • Overriding (замещение) – иная реализация метода в подклассе первоначально определившего метод класса Примитивные типы В Java существует 8 типов, кроме классов: boolean (1 бит) логический тип char (2 байта) символьный тип byte (1 байт) целочисленные типы short (2 байта) int (4 байта) long (8 байт) float (4 байта) double (8 байт) типы с плавающей точкой boolean • Нельзя писать if (5)… операция обозначение присваивание a = true; отрицание !b and (логическое “и”) a && b a&b or (логическое “или”) a || b a|b xor (исключающее “или”) a^b char • • • • Хранится в кодировке unicode. c = 'b'; c = '\077'; Где 077 – это обязательно трехзначное число, не большее чем 377 (=255 в десятичной системе счисления) • Или же в 16-ричной системе счисления следующим образом: • c = '\u12a4'; • c = '\n'; float, double Описание Выдаваемое значение Специальная константа в Java +∞ infinity Float.POSITIVE_INFINITY Double.POSITIVE_INFINITY -∞ -infinity Float.NEGATIVE_INFINITY Double.NEGATIVE_INFINITY неопределенность (Not a Number) NaN Float.NaN Double.NaN Преобразование типов • Все типы условно можно расположить «в порядке увеличения»: • byte < short < int < long < float < double • int a = 1; float f = 2.2f; f = a; • int a = 1; float f = 2.2f; a = (int)f; Операции сравнения • Для всех типов, кроме boolean, определены операции сравнения (для типа boolean можно выполнять проверку на равенство/неравенство) операция обозначение равенство == неравенство != больше > меньше < больше или равно >= меньше или равно <= Классы обертки • Byte, Short, Integer, Long, Float, Double, Boolean, Character (единственный тип, который «переименовали»). • Integer x = 1; Boolean a = false; • Integer x = new Integer(1); Some magic… public static void test1() { int a = 1; int b = 1; System.out.println("--------------"); System.out.println(a>b); System.out.println(a<b); System.out.println(a==b); } //false false true Some magic… public static void test2() { Integer a = 1; Integer b = 1; System.out.println("--------------"); System.out.println(a>b); System.out.println(a<b); System.out.println(a==b); } //false false true Some magic… public static void test3() { Integer a = 1000; Integer b = 1000; System.out.println("--------------"); System.out.println(a>b); System.out.println(a<b); System.out.println(a==b); } //false false false Some magic… public static void test4() { Integer a = new Integer(1); Integer b = new Integer(1); System.out.println("--------------"); System.out.println(a>b); System.out.println(a<b); System.out.println(a==b); } //false false false • В Java есть два способа сравнить объекты на равенство, == и метод equals. • == используется для примитивных типов. • Для объектов == это исключительно сравнение по ссылке! • Для остального надо использовать метод .equals. Кроме того, метод hashCode служит (теоретически) для той же цели. Хорошим тоном считается переопределять его, если вы переопределили equals. • Золотое правило сравнения: Если после инициализации неких объектов a и b выражение a.equals(b) вернёт true, то a.hashCode() должен быть равен b.hashCode(). Some magic – 2… class Links2 { public static void foo(Point p) { p.x = 3; } public static void main(String[] args) { Point p = new Point(0,0); foo(p); System.out.println(p.x); } } Some magic – 2… class Links3 { public static void foo(int x) { x = 3; } public static void main(String[] args) { int x = 1; foo(x); System.out.println(x); } } Some magic – 2… class Links4 { public static void foo(Integer x) { x = 3; } public static void main(String[] args) { Integer x = 1; foo(x); System.out.println(x); } } Some magic – 2… public class Links { public static void foo(String str) { str = new String("b"); } public static void main(String[] args) { String s = "a"; foo(s); System.out.println(s); } } Some magic – 2… public class Links { public static void foo(String str) { str = "b"; } public static void main(String[] args) { String s = "a"; foo(s); System.out.println(s); } }