Почему Вы называете класс дважды во время инстанцирования в Java?

Когда Вы инстанцируете объекта, почему Вы указываете класс дважды?

OddEven number = new OddEven();

Почему Вы не можете просто сказать number = new OddEven();? Когда я объявляю строку, говорю я только String однажды:

String str = "abc";

На самом деле мой вопрос не, "почему Вы делаете это этот путь" - очевидно, Вы делаете это, потому что Вы имеете к - а скорее, почему создатели принимали решение заставить синтаксис Java работать как это?

Мои мысли:

  1. Существует что-то фундаментальное для способа, которым Java работает на низком уровне, который требует вводить имя дважды, или
  2. Создатели свободно принимают решение сделать это, этот способ сохранить некоторый аспект универсальной формы синтаксиса - объявляет тип сначала? Или это быть было больше похожим на своих предшественников?
12
задан Tunaki 13 September 2016 в 15:10
поделиться

10 ответов

Потому что вы можете сделать это:

Superclass x = new Subclass();

Тип ссылки может быть суперклассом фактического объявляемого объекта, поэтому вам нужно указать оба. Например, вы можете:

List<String> stringList = new ArrayList<String>();

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

44
ответ дан 2 December 2019 в 03:04
поделиться

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

С левой стороны вы объявляете переменную (место хранения) определенного типа. Справа вы создаете новый объект определенного типа. Знак '=' в середине приводит к тому, что ссылка на новый созданный вами объект будет помещена в созданное вами место хранения.

Типы на каждой стороне не обязательно должны быть одинаковыми. Это, например, допустимый код:

Object number = new OddEven();

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

String string = new String("xxx");
5
ответ дан 2 December 2019 в 03:04
поделиться

Первое объявление - это тип переменной, которую вы хотите использовать в имеющейся у вас области, в данном случае это OddEven, второе объявление - это конструктор, который будет использоваться для создания экземпляра (и в данном случае инициализация) ссылки.

Вы могли бы сказать INumberInstance = new OddEven (), где INumberInstance - это некоторый класс, к которому может быть приведен OddEven (например, супер-класс OddEven).

0
ответ дан 2 December 2019 в 03:04
поделиться

Первый OddEven - это тип, второй - это экземпляр. Это не обязательно должно быть четное OddEven , это может быть любой подкласс OddEven . Это не значит, что вам нужно набрать его дважды. В любой среде IDE есть шаблоны кода, в которых имя нужно ввести только один раз.

0
ответ дан 2 December 2019 в 03:04
поделиться

Способ создания нового объекта в java:

Class_name reference_variable = new Class_name(param_if_any);

Но строковый класс является исключением .

Вы можете создать новый строковый объект как

String s = "abc";

или

String s = new String("abc");
0
ответ дан 2 December 2019 в 03:04
поделиться

В дополнение к тому, что сказал Джим, Java - это язык со статической типизацией. Это означает, что каждая переменная имеет тип, который известен во время компиляции.

Например:

public class A
{
    public void foo() { }
}

public class B
{
    public void foo() { }
}

public class Main
{
    public static void main(final String[] argv)
    {
        A a = new A();
        B b = new B();

        a.foo();
        b.foo();
    }
}

компилятор смотрит на «a.foo ()» и «b.foo ()» и проверяет, является ли a типа A и A имеет метод "foo", который не принимает аргументов. Компилятор делает то же самое для "b.foo ()".

Если бы вы могли написать main так:

public class Main
{
    public static void main(final String[] argv)
    {
        a = new A(); // in Java you would really do Object a = new A();
        b = new B(); // in Java you would really do Object b = new B();

        a.foo();
        b.foo();
    }
}

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

это не требует аргументов. Компилятор делает то же самое для "b.foo ()".

Если бы вы могли написать main так:

public class Main
{
    public static void main(final String[] argv)
    {
        a = new A(); // in Java you would really do Object a = new A();
        b = new B(); // in Java you would really do Object b = new B();

        a.foo();
        b.foo();
    }
}

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

это не требует аргументов. Компилятор делает то же самое для "b.foo ()".

Если бы вы могли написать main так:

public class Main
{
    public static void main(final String[] argv)
    {
        a = new A(); // in Java you would really do Object a = new A();
        b = new B(); // in Java you would really do Object b = new B();

        a.foo();
        b.foo();
    }
}

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

0
ответ дан 2 December 2019 в 03:04
поделиться

Подумайте о 'OddEven number 'как определение объекта и' new OddEven (); ' как заполнение объекта.

Я не буду вдаваться в подробности о суперклассах и подклассах, потому что другие люди уже объяснили это.

0
ответ дан 2 December 2019 в 03:04
поделиться

При записи:

OddEven number = new OddEven();

Вы фактически делаете две вещи : 1) Вы объявляете переменную номер типа OddEven и 2) Вы присваиваете ссылку на новый экземпляр класса OddEven. Но так как переменная может содержать любой подтип типа, то записи number = new OddEven(); будет недостаточно, чтобы компилятор знал реальный тип переменной number. Поэтому, вы должны объявить и это тоже. Java - это сильно типизированный язык, а это значит, что каждая переменная и каждое выражение имеет тип, известный во время компиляции. Вы можете захотеть прочитать всю Главу 4. Типы, значения и переменные спецификации языка Java (JLS), чтобы узнать больше об этом.

Теперь, когда вы пишете:

String str = "abc";

Все немного по-другому. Символы, заключенные в двойные кавычки, "abc" здесь называются строковым литералом , который уже является ссылкой на экземпляр Строки и всегда ссылается на один и тот же экземпляр класса Строки . Цитирование раздела 3.10.5 Строковые литералы JLS:

Каждый строковый литерал является ссылкой (§4.3) к экземпляру (§4.3.1, §12.5) класса String (§4.3.3). String объекты имеют постоянное значение. Строка буквально - или вообще - струны то есть значения константы expressions (§15.28)-are "интернирован", чтобы поделиться уникальным экземпляры, использующие метод String.intern.

Итак, Строковая строка str = "abc"; определенно не конвертируется в Строковая строка str = новая строка("abc");, что абсолютно не эквивалентно, как я прочитал в некоторых комментариях и ответах. Запуск следующего класса:

public class Test {
    public static void main(String[] args) {
        String one = "abc";
        String two = "abc";
        String abc = new String("abc");

        System.out.println(one == two);
        System.out.println(one == abc);
    }
}

Производит вывод ниже:

true
false

И демонстрирует, что один и два являются ссылками на один и тот же экземпляр, но abc является ссылкой на другой экземпляр (т.е. был создан лишний ненужный объект).

На самом деле, использование new String(String) является неэффективным способом построения новых строк и должно использоваться только для того, чтобы заставить подстроку скопироваться в новый базовый символьный массив, как в

String tiny = new String(monster.substring(10,20))
4
ответ дан 2 December 2019 в 03:04
поделиться

Когда вы говорите String name = "foo", внутренний компилятор Java создает строковый объект со значением "foo" и присваивает его ссылку на переменную name. Таким образом, здесь вместо создания нового объекта String мы присваиваем ссылку на другой объект String.

Btw, компилятор все равно создает для нас "foo". Сначала он смотрит в String Pool, если его нет, только потом создает "foo". В противном случае компилятор возвращает ссылку из пула строк. Это некоторая оптимизация, которую компилятор Java выполняет внутренне.

Имя строки = "foo" simlar to OddEvenNumber oddEven = anotherOddEvenObject;

0
ответ дан 2 December 2019 в 03:04
поделиться

Разработчики Java не имели , чтобы сделать синтаксис избыточным. Scala - это еще один язык, использующий JVM, и он также статически типизирован. Scala использует вывод типов , чтобы исключить многословие. Например, вот объявление переменной типа MyPair с именем x. MyPair связывает две переменные друг с другом. Это общий класс, поэтому вы можете указать, что первая переменная имеет тип Int, а вторая - тип String:

var x: MyPair[Int, String] = new MyPair[Int, String](1, "scala")

Выведение типа Scala позволяет вам удалить объявление избыточного типа:

var x = new MyPair[Int, String](1, "scala")

Scala даже определяет типы на основе аргументов конструктора. , поэтому вы можете написать это так:

var x = new MyPair(1, "scala")
0
ответ дан 2 December 2019 в 03:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: