Урок 4. переменные и типы данных java

Литералы целых чисел

А теперь новая интересная тема — литералы. Данные, вписанные прямо в код программы, называют литералами. В данном случае речь идет не о любых данных, а о значениях примитивных типов и типе .

Например, у вас есть код:

Код Литералы

Литералы в этом коде — это число , число и строка .

В языке Java тип есть у всего, включая литералы. Все целочисленные литералы (целые числа) в коде имеют тип . Тип int является стандартным типом целых чисел в Java.

При этом, если вы в своем коде решите присвоить целочисленный литерал переменной типа или , проблем не возникнет. Надо лишь чтобы значение литерала лежало внутри диапазона доступных значений типа переменной.

Компилятор в Java достаточно умный, чтобы понять, что переменной типа можно присвоить целочисленный литерал 100, и проблем не возникнет.

Примеры:

Код Описание
Скомпилируется отлично.
Скомпилируется отлично.
Будет ошибка компиляции: максимальное значение типа равно .

В коде также можно писать литералы типа . Для этого в конце целого числа нужно написать латинскую букву L или l.

Примеры:

Код Описание
Скомпилируется отлично.
Ошибка компиляции: 3 миллиарда слишком большое число для литерала типа int.
Ошибка компиляции: у литерала тип long, а у переменной тип int. К тому же, 3 миллиарда больше, чем максимальное число типа int.

Обратили внимание, как сложно читать большие числа в 10 и более знаков? Не сразу поймешь, 3 миллиарда в коде или 30? Чтобы упростить читаемость кода (а это важно!), в Java разрешили вставлять в числовые литералы символы подчеркивания (на значение числа они не влияют). Пример выше можно переписать с использованием символов подчеркивания, и он станет немного понятнее:

Пример выше можно переписать с использованием символов подчеркивания, и он станет немного понятнее:

Код Описание
Скомпилируется отлично.
Ошибка компиляции: 3 миллиарда слишком большое число для литерала типа int.
Ошибка компиляции: у литерала тип long, а у переменной тип int. К тому же 3, миллиарда больше, чем максимальное число типа int.

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

Литералы вещественных чисел

В коде можно задавать не только целочисленные, но и литералы с плавающей точкой (вещественные числа).

Собственно, правило очень простое: если в коде есть число и в его записи есть точка, это число — литерал с плавающей точкой. И не просто литерал, а литерал с типом .

Можно создать и литерал типа float, но для этого к числу в конце нужно приписать букву F (или f).

Примеры:

Код Описание
Скомпилируется отлично.
Скомпилируется отлично.
Скомпилируется отлично.
Скомпилируется отлично.
Будет ошибка компиляции: переменная типа float, литерал типа double.

Кстати, можно явно превратить целочисленный литерал в литерал типа float или double, просто приписав к нему суффикс F (для ) или D (для ). Примеры:

Код Описание
Скомпилируется отлично.
Скомпилируется отлично.
Будет ошибка компиляции: переменная типа int, литерал типа .

У литералов с плавающей точкой есть «научная форма записи»: кроме знаковой части числа можно еще указать и степень десятки этого числа. Пример:

Литерал Математическая запись Итоговое значение

Методы

Последнее обновление: 17.04.2018

Если переменные и константы хранят некоторые значения, то методы содержат собой набор операторов, которые выполняют определенные действия.

Общее определение методов выглядит следующим образом:

 тип_возвращаемого_значения название_метода (){
	// тело метода
}

Модификаторы и параметры необязательны.

По умолчанию главный класс любой программы на Java содержит метод main, который служит точкой входа в программу:

public static void main(String[] args) {
	System.out.println("привет мир!");
}

Ключевые слова и являются модификаторами. Далее идет тип возвращаемого значения.
Ключевое слово указывает на то, что метод ничего не возвращает.

Затем идут название метода — main и в скобках параметры метода — . И в фигурные скобки заключено тело метода — все действия,
которые он выполняет.

Создадим еще несколько методов:

      
public class Program{
     
	public static void main (String args[]){
         
    }
	void hello(){
		
		System.out.println("Hello");
	}
	void welcome(){
		
		System.out.println("Welcome to Java 10");
	}
}

Здесь определены два дополнительных метода: hello и welcome, каждый из которых выводит некоторую строку на консоль. Методы определяются внутри класса — в данном случае внутри класса Program,
в котором определен метод main.

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

Вызов метода осуществляется в форме:

имя_метода(аргументы);

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

Например, определим и выполним несколько методов:

public class Program{
     
	public static void main (String args[]){
         
		 hello();
		 welcome();
		 welcome();
    }
	static void hello(){
		
		System.out.println("Hello");
	}
	static void welcome(){
		
		System.out.println("Welcome to Java 10");
	}
}

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

Также следует отметить, что чтобы вызвать в методе main другие методы, которые определены в одном классе с методом main, они должны иметь модификатор
.

В итоге после компиляции и выполнения программы мы увидим на консоли:

Hello
Welcome to Java 10
Welcome to Java 10

НазадВперед

Число

Числовой тип данных () представляет как целочисленные значения, так и числа с плавающей точкой.

Существует множество операций для чисел, например, умножение , деление , сложение , вычитание и так далее.

Кроме обычных чисел, существуют так называемые «специальные числовые значения», которые относятся к этому типу данных: , и .

  • представляет собой математическую ∞. Это особое значение, которое больше любого числа.

    Мы можем получить его в результате деления на ноль:

    Или задать его явно:

  • означает вычислительную ошибку. Это результат неправильной или неопределённой математической операции, например:

    Значение «прилипчиво». Любая операция с возвращает :

    Если где-то в математическом выражении есть , то результатом вычислений с его участием будет .

Математические операции – безопасны

Математические операции в JavaScript «безопасны». Мы можем делать что угодно: делить на ноль, обращаться с нечисловыми строками как с числами и т.д.

Скрипт никогда не остановится с фатальной ошибкой (не «умрёт»). В худшем случае мы получим как результат выполнения.

Специальные числовые значения относятся к типу «число». Конечно, это не числа в привычном значении этого слова.

Подробнее о работе с числами мы поговорим в главе Числа.

Переменные и типы данных в Java.

В языке Java не так уж и много типов данных. Возьмём примитивные: их всего 8. Представляете? Если вы учили английский язык и хоть сколько-нибудь информатику в школе, названия по меньшей мере половины этих примитивных типов вам будут знакомы. Если вы учили французский или казахский(как я в школе), а на информатике рубились в Денди, Сегу, то вам придется попотеть. Возьмите ручку и перепишите себе в блокнотик 8 страшных буржуинских слов. Они нам понадобятся, честно.byte (числа от -128 до 127, 1 байт).short (Тоже легкотня. Целые числа  от -32768 до 32767, 2 байта).int (Это мой любимый тип. С ним мы будем работать чаще всего. Его диапазон таков: -2147483648 до 2147483647, 4 байта). Когда я первый раз пыталась вникнуть в число 2147483647, я сделала так: сначала посмотрела на последние три циферки: 647. Потом на три цифры 483, которые стояли перед 647. У меня вышло 483 тысячи 647. А потом получилось 147 миллионов, 483 тысячи 647. Короче, в этом числе два с лишним миллиарда. Я вообще на этом месте подумала: Куда нахрен, больше? И хотела перестать изучать примитивные типы — мне диапазон в 4 с хвостиком лярда показался вполне ничего. Но — надо идти дальше. Стисните зубы, и за мной. К лонгу.

long (целые числа, внимание: -9223372036854775808 до 9223372036854775807, 8 байт). Лично я ассоциирую это число с обожравшейся змеёй

Играли же в змейку на кнопочной Nokia? Snake, вроде по-английски. Вот даже не пыталась посчитать, сколько там диапазон. Хотите, посчитайте и потом вслух нам, словами, напишете. Для потомков. Я даже ради такого дела комменты сегодня подключу. Чтобы можно было увидеть героя нашего времени. В моем сознании этот тип отложился как длинная змея. long snake, мать ее.

float (вещественные числа, 4 байта). Вот честно, я очкую такое писать, про диапазон их. Но вариантов нет. Просто смиритесь с этим. Диапазон от ~1,4*10-45 до ~3,4*1038 Где использовать флоат? Ну например, при расчете курса доллара к тенге. Буковка ф на конце — нечто вроде напоминалки. Чтобы мы помнили: это тип флоат. Она нужна.double (вещественные числа, 8 байт). Диапазон этих — от ~4,9*10-324 до ~1,8*10308. Короче, это — важный тип. Если требуется точность, например, надо написать программку для конвертации градусов Цельсия в Фаренгейты или наоборот, произвести расчеты объема, квадратуры, это сделает double.char (символ Unicode, 2 байта). Вот здесь можете выдохнуть. Главное, что я должна сказать о типе char — Это символьный тип, представляющий собой ОДИН 16-битный символ Юникод

Если вы сейчас в шоке и в душе не е представляете, что такое Uniсode символы, ща покажу:)
Откройте ворд, или поисковик( Гугл, яндекс, неважно. Важно, чтобы было, где напечатать символ.) нажмите на клавиатуре кнопку alt и не отпуская ее, нажмите на 3

А теперь alt и 15. alt 11, alt 12.boolean (значение истина/ложь, 1 байт) — Здесь все просто. Тип данных Булеан или Булиан просто создан для того, чтобы хранить в себе логические значение true / false. Либо истина, либо ложь. Третьего не дано. Шекспиром повеяло. «Быть или не Быть, вот в чем Boolean.»

Я чувствую, что сегодня информации более чем достаточно. Но это еще не всё. Есть еще такой тип, который к примитивным не относится, но пройти его надо прямо сейчас. Просто он используется настолько часто, что лучше не откладывать это знакомство.

Тип String в Java, во всей своей красе.

Ага, знаете его?
Вы правы, он очень простой и веселый. С ним можно печатать что угодно, переменные типа String хранят в себе строковые данные. Помните, мы в задании при помощи этого типа пробовали поздороваться с миром? А там ведь можно не только здороваться. Можно и в пешее путешествие отправить, матюками прям. Потренируйтесь. Хоть мир, хоть соседского кота Барсика.
Есть еще крутая фишка про Стринг.

public static void main(String[] args) {

	String s1 = "Барсик ";
	String s2 = " гон";
	int num = 3;
        String s3 = "жды ";
        String s4 = "дон ";
        String s5 = " года ";
        String s6 = " - ";
        String s7 = " кот "

	String s = s1 + num + s5;

	System.out.println(s);
}

Объявляешь переменные, а потом просто «складываешь» их. Про операторы «+» и «=» вам тоже понравится. Они не так просты, как вы думали все эти годы.

Класс Double

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

Интересных полей у класса шесть:

Поле Описание
Минус бесконечность
Плюс бесконечность
Минимальное значение экспоненты (2x)
Максимальное значение экспоненты (2x)
Минимальное значение типа
Максимальное значение типа

Бесконечность

Если вы разделите на , получите отрицательную бесконечность, если на — положительную бесконечность. Тип может не только делить на ноль, но и хранить такие значения.

Экспонента числа

С экспонентой тоже все просто. Число double внутри состоит из мантисы и экспоненты. Только вот значение экспоненты — это не , а . Если экспонента вырастет на , итоговое значение числа станет больше в два раза.

, в итоге получаем примерно равно

Также у класса есть интересные методы:

Методы Описание
Возвращает строку — шестнадцатеричное представление числа
Проверяет, является ли переданное число бесконечностью.
Проверяет, является ли переданное число
Оборачивает переданный в
Возвращает число, полученное из строки

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

Аналогично работает и метод — проверяет, является ли переданное в него число : специальная константа, обозначающая неопределенность (Not a Number, Не число).

Абстрактный класс и интерфейс

  • В интерфейсе отсутствует код реализации, а все методы являются абстрактными. То есть, все методы объявляются, но ни один не определяется.
  • В абстрактном классе есть исполняемые и абстрактные методы.
  • Класс реализует сколько угодно интерфейсов, но расширяет только один абстрактный класс.
  • Методы абстрактного класса могут быть или не быть абстрактными.
  • Абстрактный класс не может превратиться в экземпляр, но может стать подклассом.
  • Все абстрактные методы должны определяться в подклассе, то есть, подкласс является абстрактным.
  • Создавать экземпляры из интерфейса нельзя. Их можно реализовывать в других классах или расширять другими интерфейсами.
  • Переменные интерфейсов конечные и статические. По умолчанию, все методы интерфейса публичные и абстрактные.
  • Интерфейс не может содержать реализацию и не может превращаться в подкласс. Все переменные должны быть постоянными.

Тип double

Для работы с вещественными (дробными) числами в Java используется тип . В памяти он занимает (в два раза больше, чем тип ) и может хранить значения в диапазоне до . Для сравнения: тип может хранить значение в диапазоне до .

В вещественных числах дробная часть записывается после точки. Например, 123.456, или 2.5, или 100.00 или 0.01. Такие числа еще называют числами с плавающей точкой — floating point number – компьютерное название для вещественных чисел.

Кстати, кроме типа есть еще вещественный тип (размером всего 4 байта). Его название как раз и происходит от floating point. Название же происходит от double float. Тип в два раза больше, чем : против . Его еще называют вещественное число двойной точности.

Литералы строк

В коде также можно задавать и целые строки текста. Чтобы компилятор считал строку именно данными (строкой текста), а не частью кода, вся строка с двух сторон обрамляется двойными кавычками.

Если в одной строке кода много двойных кавычек, они разбиваются на пары. Первая двойная кавычка обозначает начало литерала, следующая за ней — конец литерала. Следующая за ней — опять начало нового литерала, следующая за ней — конец второго литерала. И т.д.

Каждый такой литерал имеет тип .

Примеры

Код Пояснение
В строке 5 литералов, каждый из которых состоит из одного символа 
Литерал пустая строка. Строка, в которой нет символов.
Тут два литерала. Результатом будет строка , но не число
Тут тоже два литерала. Оператора return тут нет.

Если строковый литерал слишком длинный, его можно разбить на несколько строк и склеить «оператором плюс»:

Код Пояснение
Если вывести эту строку на экран, весь текст выведется в одну строку!

Неявное

Тип приведения, когда два типа данных автоматически конвертируются. Также известно как неявное преобразование. Происходит, когда два типа данных совместимы, а также когда мы присваиваем значение меньшего типа данных большему типу данных.

Кроме того, char и boolean не совместимы друг с другом. Теперь давайте напишем логику для неявного приведения типов, чтобы понять, как это работает.

public class Conversion{
public static void main(String[] args)
{
int i = 200;

//automatic type conversion
long l = i;

//automatic type conversion
float f = l;
System.out.println("Int value "+i);
System.out.println("Long value "+l);
System.out.println("Float value "+f);
}
}

Вывод:

Int value 200
Long value 200
Float value 200.0

Тип char в Java

Тип данных char основан на шестнадцатибитных символах Unicode. Unicode позволяет вам указать все символы большинства наборов символов для языков мира. ‘\ u’ перед шестнадцатеричными кодами означает, что символ является юникодом. Он имеет минимальное значение ‘\ u0000’ (или 0) и максимальное значение ‘\ uffff’. В отличие от C, Java не поддерживает подписанные символы. Разработчики Java считали, что подписанные символы и неподписанные номера являются источниками ошибок программы.

Python

char cr =’a’;

1 char cr=’a’;

Кроме того, Java поддерживает ряд других escape-символов, которые облегчают представление как обычно используемых непечатаемых символов ASCII, таких как newline, и для избежания определенных символов пунктуации, которые имеют особое значение в Java. Например:

char backspace = ‘\ b’;

char tab = ‘\ t’;

Расширение типов

Часто может возникнуть необходимость присвоить переменной одного числового типа значение переменной другого числового типа. Как же это сделать?

В Java есть 4 целочисленных типа:

Тип Размер

Переменной большего размера всегда можно присваивать переменные меньшего размера.

Переменной типа спокойно можно присваивать переменные типа , и . Переменной типа можно присваивать переменные типа и . Ну и переменной типа можно присваивать переменные типа .

Примеры:

Код Описание
Этот код отлично скомпилируется.

Такое преобразование, от типа меньшего размера к большему, называется расширением типа.

А что насчет вещественных чисел?

С ними все аналогично — размер имеет значение:

Тип Размер

Переменной типа можно без проблем присвоить переменную типа . А вот с целочисленными типами интереснее.

Переменной типа можно присвоить переменную любого целочисленного типа. Даже типа , длина которого 8 байт. А переменной типа можно присвоить вообще что угодно: переменную любого целочисленного типа и переменную типа :

Код Примечание

Обратите внимание, что преобразование к вещественному типу может привести к потере точности из-за нехватки значащих цифр. При преобразовании из целых чисел в дробные могут отбрасываться самые младшие части числа

Но т.к. смысл дробного числа в том, чтобы хранить приблизительное значение, такое присваивание разрешается

При преобразовании из целых чисел в дробные могут отбрасываться самые младшие части числа. Но т.к. смысл дробного числа в том, чтобы хранить приблизительное значение, такое присваивание разрешается.

Автобокс

До Java 5 вам приходилось вызывать методы для объектных примитивных типов, чтобы получить их значение:

Integer myInteger = new Integer(45);

int myInt = myInteger.intValue();

С Java 5 у вас есть понятие, называемое «автобокс». Это означает, что оболочка может автоматически «упаковывать» примитивную переменную в объектную версию или «распаковывать» объектный примитив. В зависимости от того, что требуется. Предыдущий пример может быть написан так:

Integer myInteger = new Integer(45);

int myInt = myInteger;

В этом случае Java автоматически извлечет int из myInteger и присвоит это значение myInt.

Точно так же создание объектной примитивной переменной было ручным действием:

int myInt = 45;

Integer myInteger = new Integer(myInt);

С помощью автобокса оболочка может сделать это за вас. Теперь запись выглядит так:

int myInt = 45;

Integer myInteger = myInt;

Затем Java автоматически «упаковывает» примитив в объектную версию соответствующего типа.

Функции автобокса позволяют использовать примитивы, для которых обычно требовалась его объектная версия и наоборот. Есть одна ловушка. Переменная object (ссылка) может указывать на ноль, то есть на ничто. Если попытаетесь преобразовать ноль в примитивное значение, получите исключение NullPointerException (ошибка, которая приводит к сбою программы). Этот код показывает пример этого:

Integer myInteger = null;

int myInt = myInteger;

Этот код будет хорошо скомпилирован, но при выполнении он приведет к исключению NullPointerException, поскольку myInteger указывает на ноль. Таким образом, невозможно преобразовать (распаковать) значение объекта, на который он указывает, поскольку не указывает ни на один объект.

Объявление и инициализация переменных

В общем случае при объявлении переменной в C#, вначале указывается тип данных переменной, затем ее имя:

int nVal;
string strVal;

Задание значения переменной можно произвести в момент инициализации:

int radius = 10;
string name = "John";

либо после инициализаций:

string name;
name = "John";

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

int notInitedVal;
Console.Write(notInitedVal);

В примерах мы не будем приводить код импорта и объявления класса. В конце главы будет приведен листинг программы со всеми примерами из данного урока.

Ключевое слово new

Ключевое слово new, как правило, используется при инициализации переменных, которые имеют ссылочный тип данных. О том, что это такое мы расскажем чуть ниже. Пусть у нас есть класс Rectangle

class Rectangle
{
    public double Width = 0;
    public double Height = 0;
}

Данный класс нам нужен только для демонстрации, при разработке собственных классов не стоит создать поля с ключевым словом public. О создании классов и основах объектно-ориентированного программирования будет рассказано в одном из ближайших уроков.

Создадим переменную класса Rectangle

Rectangle rect = new Rectangle();
Console.WriteLine($"Rectangle Width={rect.Width}, Height={rect.Height}");

Переменные типа int, double и т.п. также можно проинициализировать с помощью ключевого слова new, в этом случае будет присвоено значение по умолчанию:

int newInitedValue = new int();
Console.WriteLine("Default int value: " + newInitedValue);

Ключевое слово var. Неявная типизация

При объявлении переменной вместо явного задания типа можно поставить ключевое слово var. В этом случае будет использована система вывода типов для определения типа переменной по ее значению.

int v1 = 12345;
var v2 = 12345;

Console.WriteLine($"Type of v1: {v1.GetType()}\nType of v2: {v2.GetType()}");

При работе с var необходимо помнить следующее:

  • использовать var можно только для объявления локальных переменных;
  • var нельзя использоваться для объявления типа возвращаемого значения, типов полей и параметров;
  • при объявлении переменной с использованием var она обязательно должна быть проинициализирована, при этом использовать для этого null запрещено;
  • объявлять переменную допускающую null-значение с использованием лексемы ? через var нельзя.

2.2 Типы с плавающей точкой (Floating-point Types)

Литералы с плавающей точкой могут быть записаны в научной нотации с помощью символа E (или e) означающего в данном контексте экспоненту.  Например, double-литерал 194.9E-2 в научной нотации интерпретируется как 194.9 × 10-2 (т.е. 1.949).

Десятичная точка и экспонента для чисел с плавающей являются опциональными и указываются при необходимости. Однако как минимум одна цифра должна быть указана.

2.2.1 float

Для литерала с плавающей точкой может быть указан тип float для этого нужно добавить к значению суффикс F (или f).

Примеры float-литералов

Для float-литералов суффикс F является обязательным, иначе они будут считаться double-литералами.

Методы класса

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

Метод класса — это блок кода, состоящий из ряда инструкций, который можно вызывать по его имени. Он обязательно содержит возвращаемый тип, название, аргументы и тело метода.

Синтаксис метода в Java:

Строка возвращаемыйТип показывает, какого типа данные вернёт метод. Например, если в качестве возвращаемого типа мы поставим тип String, то метод должен будет вернуть строку, а если int — целое число.

Чтобы вернуть значение из метода, используется специальное слово return. Если мы хотим, чтобы метод ничего не возвращал, то вместо возвращаемого типа нужно использовать специальное слово void.

Аргументы — то, что нужно передать в метод при его вызове. Мы можем указать сколько угодно параметров через запятую либо не указывать ни одного.

Для примера напишем простейший метод с именем sum (пока что не в нашем классе Pet), который складывает два переданных числа и возвращает их результат:

Возвращаемый тип метода int, он указан перед именем sum. Далее идут два аргумента a и b, у обоих также указан тип int

Важно помнить, что возвращаемый тип и тип переменных не обязательно должны совпадать

Аргументы метода работают как обычные переменные — за пределами метода к ним никак нельзя получить доступ. Внутри метода мы складываем значения из переменных a и b, записываем полученное значение в переменную c. После этого мы возвращаем значение переменной c — только оно доступно вне метода.

Вот пример:

Мы передали в метод sum два значения 1 и 2, а на выходе получили результат их сложения 3. Также можно создать метод, который принимает значение типа String, а возвращает длину этой строки:

В этом случае у нас возвращаемый типа int, а параметр str — типа String.

Попробуем использовать этот метод:

Также мы можем создать метод, который ничего не возвращает, а просто печатает переданное слово в консоль:

Либо метод, который ничего не принимает на вход, а просто печатает «Привет!»:

В методах, которые ничего не возвращают, слово return можно опустить.

Обратите внимание, что return полностью прекращает выполнение метода:

Теперь попробуем вызвать этот метод, передав в него число 3:

В этом случае мы ничего не увидим в консоли, так как 3 меньше 5, а значит, отработает блок if и произойдёт выход из метода с помощью слова return.

Но если передадим 6, увидим нашу надпись «Привет!»:

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

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

Adblock
detector