Примитивные типы
- byte (8 бит): [-128...127]
- short (16 бит): [-32768 ... 32767]
- int (32 бит): [-2147483648 ... 2147483647]
- long (64 бит): [-9223372036854775808 ... 9223372036854775807]
Примитивные типы
- char (16 бит): ['\u0000' ... '\uffff']
- float (32 бит)
- double (64 бит)
- boolean: false, true
Числа с плавающей точкой
- float: точность 24 бита, ~7 знаков после запятой
- double: точность 53 бита, ~16 знаков после запятой
Числа с плавающей точкой
public class Main {
public static void main(String[] args) {
float f = 0.0f;
for (int i=1; i <= 7; i++) {
f += 0.1111111111111111;
}
System.out.println(f);
}
}
Результат: 0.7777778
Числа с плавающей точкой
public class Main {
public static void main(String[] args) {
double f = 0.0f;
for (int i=1; i <= 7; i++) {
f += 0.1111111111111111;
}
System.out.println(f);
}
}
Результат: 0.7777777777777779
Числа с плавающей точкой
public class Main {
public static void main(String[] args) {
//прибавляем к нулю 0.1 одиннадцать раз подряд
double f1 = 0.0;
for (int i = 1; i <= 11; i++) {
f1 += .1;
}
//Умножаем 0.1 на 11
double f2 = 0.1 * 11;
//должно получиться одно и то же - 1.1 в обоих случаях
System.out.println("f1 = " + f1);
System.out.println("f2 = " + f2);
// Проверим!
if (f1 == f2)
System.out.println("f1 и f2 равны!");
else
System.out.println("f1 и f2 не равны!");
}
}
f1 = 1.0999999999999999
f2 = 1.1
f1 и f2 не равны!
Числа с плавающей точкой
final double threshold = 0.0001;
if (Math.abs(f1 - f2) < threshold)
System.out.println("f1 и f2 равны");
else
System.out.println("f1 и f2 не равны");
ООП
- Класс
- Объект класса
- Поля
- Методы
- Наследование
- Интерфейсы
Класс
public class HelloWorld {
public static void say(String str) {
System.out.println(str);
}
public static void main(String[] args) {
say("Hello");
say("World!");
}
}
Точка входа, JAR
manifest.mf:
Manifest-version: 1.0
Main-Class: HelloWorld
javac HelloWorld.java
jar cfm hw.jar manifest.mf HelloWorld.class
java -jar hw.jar
Класс Object
- Все классы наследуются от Object (явно или неявно).
- toString()
- hashCode()
- equals(Object obj)
- getClass()
- finalize()
Экземпляр класса
package ru.petrsu.cross;
public class Say {
public void say(String str) {
System.out.println(str);
}
}
import ru.petrsu.cross.Say;
public class HelloWorld {
public void main(String[] args) {
Say s = new Say();
s.say("Hello");
s.say("World!");
}
}
Экземпляр класса
- Say располагаем по имени пакета (ru/petrsu/cross)
- Компилируем Say: javac Say.java
- Компилируем HelloWorld: javac -cp . HelloWorld.java
- Запускаем HelloWorld: java -cp . HelloWorld
Абстрактный класс
- abstrac - метод только описан, но не реализован, класс содержит абстрактные методы.
package ru.petrsu.cross;
public class Say {
public void say(Anymal animal) {
System.out.println(animal.say());
}
}
package ru.petrsu.cross;
abstract public class Animal {
abstract public String say();
}
Абстрактный класс
package ru.petrsu.cross;
public class Dog extends Animal {
public String say() {
return "Hav";
}
}
import ru.petrsu.cross.Say;
import ru.petrsu.cross.Dog;
public class HelloWorld {
public static void main(String[] args) {
Say s = new Say();
s.say(new Dog());
}
}
final
- Переменная класса final - инициализируется при объявлении или в теле конструктора.
- public static final - константы, значение не меняется.
- final метод - нельзя переопределить в классе наследнике
- final класс - нельзя наследовать.
Другие модификаторы
- synchronized - метод, для которого осуществляется блокировка доступа к ресурсу
- transient - переменная не должна быть сериализована
- native - метод реализован на C или другим платформо-зависимым способом
- volatile - переменная не должна оптимизироваться
synchronized
public class Main {
private Object obj = new Object();
public void doSomething() {
//...какая-то логика, доступная для всех потоков
synchronized (obj) {
//логика, которая одновременно доступна только для одного потока
}
}
}
Сериализация.
- Сохранение/восстановление объектов в/из потока.
- Встроен в Java машину.
- Сериализуемый объект должен состоять тоже только из сериализуемых объектов.
- Интерфейс-маркер – Serializable
Сериализация.
class Dog implements Serializable
{
public String name;
public int age;
public int weight;
}
Сериализация.
public static void main(String[] args) throws Exception
{
Dog dog = new Dog();
//save cat to file
FileOutputStream fileOutput = new FileOutputStream("dog.dat");
ObjectOutputStream outputStream = new ObjectOutputStream(fileOutput);
outputStream.writeObject(dog);
fileOutput.close();
outputStream.close();
//load cat from file
FileInputStream fiStream = new FileInputStream("dog.dat");
ObjectInputStream objectStream = new ObjectInputStream(fiStream);
Object object = objectStream.readObject();
fiStream.close();
objectStream.close();
Dog newDog = (Dog)object;
}
transient
class Dog implements Serializable
{
public String name;
public int age;
public int weight;
transient public InputStream in = System.in;
}
native
- Java Native Interface (JNI) — стандартный механизм для запуска кода, под управлением виртуальной
машины Java (JVM), который написан на языках С/С++ или Ассемблера.
- Модификатор может быть применен только к методам, но не классам и переменным.
- Тело нативного метода должно заканчиваться на (;) как в абстрактных методах, идентифицируя то, что реализация опущена.
native
package ru.petrsu.cross;
public class JNIHelloWorld {
native void printHelloWorld();
}
native
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class ru_forwolk_test_JNIHelloWorld */
#ifndef _Included_ru_forwolk_test_JNIHelloWorld
#define _Included_ru_forwolk_test_JNIHelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: ru_forwolk_test_JNIHelloWorld
* Method: printHelloWorld
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_ru_forwolk_test_JNIHelloWorld_printHelloWorld
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Генерируется из исходников:
javah ru.forwolk.test.JNIHelloWorld
native
#include
#include "JNIHelloWorld.h"
JNIEXPORT void JNICALL Java_ru_forwolk_test_JNIHelloWorld_printHelloWorld
(JNIEnv *, jobject) {
std::cout << "Hello world!";
}
Компиляция: g++ -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -fPIC JNIHelloWorld.cpp -shared -o helloworld.so -Wl,-soname -Wl,--no-whole-archive
native
package ru.petrsu.cross;
public class JNIHelloWorld {
native void printHelloWorld();
static {
System.load(System.getProperty("PROJECT_ROOT") + "/bin/helloworld.so"); //Absolute path!
}
}
public static void main(String[] args) {
JNIHelloWorld p = new JNIHelloWorld();
p.printHelloWorld();
}
volatile
- Многопоточное программирование.
- Атомарно читаться и записываться.
- Java-машина не будет помещать ее в кэш.
- Метод yield()
Интерфейсы
- Прототип класс с методами без реализации.
- Имплементация методов в классе, который реализует интерфейс.
Интерфейсы
interface Animal {
public String say();
}
public class Dog implements Animal {
public String say() {
return 'Hav';
}
}
Интерфейсы vs абстрактный файл
- Интерфейс описывает только поведение. У него нет состояния.
- У абстрактного класса состояние есть: он описывает и то, и другое.
- Абстрактный класс связывает между собой и объединяет классы, имеющие очень близкую связь.
- В то же время, один и тот же интерфейс могут реализовать классы, у которых вообще нет ничего общего.
- Классы могут реализовывать сколько угодно интерфейсов, но наследоваться можно только от одного класса.
Аннотации
- Метаданные для функции/класса/пакета.
- Работают на этапе компиляции и в runtime.
- Отслеживать правильность кода, его анализировать
- Оптимально для API, библиотек.
- Стандартные аннотации и пользовательские.
Аннотации
- SOURCE - аннотации для компилятора
- CLASS - данные из аннотации будут записаны в байткод но недоступны во время работы. Пишут, что в стандартной библиотеке много аннотаций используют этот вид, и сейчас его держат из-за обратной совместимости. Применяется для очень специфичных задач.
- RUNTIME - самые популярны, используются во время работы кода.
Source Аннотации
- Native – переменная под этой аннотацией может ссылаться на нативынй код.
- SuppressWarnings – подавляет различные предупреждения компилятора.
- Generated – маркирует исходных код, который был сгенерирован.
- Override – проверяет переопределение метода.
Source Аннотации
package lombok;
public class Chelovek {
private String name;
private int age;
public Chelovek(String name, int age) {
this.name = name;
this.age = age;
}
public Chelovek() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Source Аннотации
package lombok;
@Data
public class Chelovek {
private String name;
private int age;
}
Библиотека lombok
- @Getter/@Setter
- @ToString
- @EqualsAndHashCode
- @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor
- @Log