Разница между динамическими и статическими назначениями типов в Java

учитывая иерархию классов follow, каковы динамические и статические типы для следующих операторов?

иерархия классов:

class Alpha {}

class Beta extends Alpha {}

class Gamma extends Alpha {}

class Epsilon extends Alpha{}

class Fruit extends Gamma{}

class Golf extends Beta {}

class Orange extends Fruit{}

для каждого из следующих операторов статический тип? Динамический Тип?:

Fruit f = new Fruit();
Alpha a = f;
Beta b = f;
a = b;
Gamma g = f;

мои ответы/вопросы
Я понимаю это Fruit f = new Fruit() будет как статического, так и динамического типа фруктов.
Alpha a = f; будет иметь тип Alpha во время компиляции (статический) и тип Fruit во время выполнения (динамический.)
Gamma g = f; будет иметь тип Gamma во время компиляции (статический) и тип Fruit во время выполнения (динамический).
Однако я не знаю двух других ответов. Beta b = f-это экземпляр, в котором два подкласса одного и того же суперкласса назначаются друг другу, поэтому я не уверен, будет ли он иметь тип Beta или тип Alpha во время компиляции (статический). И a = b-это задание после объявления, поэтому я не уверен, каким будет ответ на это. Кто-нибудь, пожалуйста, помогите мне спасибо!

5 ответов


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

я понимаю, что Fruit f = new Fruit () будет иметь как статический, так и динамический тип Fruit.

я думаю, что вы немного путаете термины static and dynamic типы с типами времени компиляции и времени выполнения (или как в C++, когда вы назначаете адрес объекта типа A указателю типа B С B, являющимся родительским классом А.)

за исключением трюков отражения, в Java нет динамического ввода. Все статически тип во время компиляции. Тип объекта во время выполнения совпадает с типом, в который он был скомпилирован.

происходит то, что вы путаете ссылки на объекты (a, b, c, f) с фактическими объектами, созданными в куче (все, что создано с new.)

В Java, f - это ссылка на объект, а не сам объект. Кроме того, тип ссылки из f is Fruit and sub-classes of it. Объект (new Fruit()), который вы назначаете ему, бывает типа Fruit.

теперь все остальные ссылки в вашем примере кода типа reference to A and sub-classes of it; b имеет тип reference to B and sub-classes of it; etc, etc.

имейте это в виду, потому что это очень важно.

Alpha a = f; будет иметь тип Alpha во время компиляции (статический) и тип Fruit во время выполнения (динамический).

A имеет тип 'ссылка на тип A и подклассы". f относится к типу "ссылка на тип фруктов и подклассы".

объект, на который указывает f, имеет тип "Fruit". Когда вы говорите "a = f", вы не присваиваете " f ""a". Вы говорите: "a теперь будет ссылаться на то, на что в настоящее время ссылается f".

Итак, после этого задания, что такое a ссылки? Объект типа Fruit объект ссылки f указал на момент назначения.

помните, a, b, g, f, они не являются объектами. Это ссылки или дескрипторы на объекты, созданные так или иначе с помощью new оператора.

ссылочная переменная, такая как a, b или f, отличается от объектов, созданных с помощью new. Но так уж случилось, что первое может указывать на второе.

тип объекта, созданного с помощью new во время выполнения, совпадает с типом, определенным во время компиляции.

Gamma g = f; будет иметь тип Gamma при компиляции время (статическое) и введите фрукты во время выполнения (динамическое).

то же, что и выше. Переменная g является ссылкой на объект типа reference to type Gamma and sub-classes. В этом задании g делается, чтобы указать на тот же объект, на который указывает f. Что это за объект? То же самое, что и во время компиляции: фрукты.

однако я не знаю двух других ответов. Beta b = f является экземпляром в которой два подкласса одного и того же суперкласса назначаются одному другой, поэтому я не уверен, будет ли он типа Beta или типа Alpha в время компиляции (статическая).

b имеет тип reference to type Beta and sub-classes of it. Объект на который он указывает после назначения b = f типа Fruit, тип, который он имел во время компиляции.

  1. тип ссылок на объекты a, b, g и f определяется во время компиляции. Они статически типизированы и не изменяются во время выполнения.

  2. тип объекта, созданного с new также определяется во время компиляции. Они также статически типизированы и не изменяются во время выполнения.

  3. объекты, объект stuff ссылается на a, b, g и F указывают на во время, это определяется тем, являются ли операторы действительными компилятором. Назначения могут изменяться, но это не имеет ничего общего с тем, являются ли ссылки на объект или сами объекты статически или динамически типизированный.

если вы хотите увидеть четкое различие между динамической и статической типизации рассмотрим следующее:

// Java, statically typed.
int x = 3;
x = 5; // good
x = "hi"; // compiler error

## Ruby, dynamically typed
x = 3 # ok
x = 5 # ok
x = "hi" # still ok

тогда есть различие между сильно типизированными и слабо/утка типизированных языков (оба из которых могут быть динамически типизированы. На эту тему существует много литературы.

надеюсь, что это помогает.


динамические и статические типы для следующих инструкций

Erm, оператор не имеет типа, по крайней мере, нет такого понятия в спецификации языка Java. Спецификация определяет два различных типа:объявленного типа переменной, поля или параметра, а во время выполнения класс объекта.

как следует из названия,объявленного типа переменной, поля или параметр-это тип, который вы упоминаете в объявлении. Например, декларация Foo bar; объявляет переменную с именем bar типа Foo.

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

код:

Integer i = 1;
Number n = i;
Object o = n;

объявляет 3 переменные типа Integer, Number и Object, соответственно, все они относятся к одному объекту с классом времени выполнения Integer.


конкретный, тип выполнения f фрукты (как вы правильно указали в своем вопросе).

так Beta b = f; инициализирует переменную, объявленный тип времени компиляции-Beta, а тип среды выполнения-Fruit. Однако это не будет компилироваться, потому что тип времени компиляции f Это фрукты, а фрукты не подкласс бета, так что f не может быть присвоена переменной типа Beta.

на a = b;, b, чей тип выполнения-Fruit (см. выше) назначается к переменной a, заявленный как Alpha a. Так что aтип времени компиляции-Alpha, а тип времени выполнения-Fruit.


сначала, чтобы уточнить тип "ссылочная переменная":

Object obj;

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

Object obj = new String();
System.out.println(obj.getClass());//prints class java.lang.String

obj указывает на строку, а ссылочная переменная obj имеет тип String.

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

Object obj = new String();
System.out.println(obj.getClass());//prints class java.lang.String
Number num = new Byte((byte)9);
obj = num;
System.out.println(obj.getClass());//prints class java.lang.Byte

во время выполнения, как и во время компиляции, ссылочная переменная obj имеет тип Byte.

статический / динамический тип объекта, для меня, имеет отношение к наследованию. Более конкретно, механизм переопределения. Также известный как динамический полиморфизм и позднее связывание.

рассмотрим переопределение equals () в объекте класса:

public class Types {

    @Override
    public boolean equals(Object obj){
        System.out.println("in class Types equals()");
        return false;//Shut-up compiler!
    }

    public static void main(String[] args){
        Object typ = new Types();
        typ.equals("Hi");//can do this as String is a subclass of Object
    }
}

теперь мы знаем, что тип ссылочной переменной typ Типы.

Object typ = new Types();

когда дело доходит до

typ.equals("Hi");

вот как, я думаю, думает компилятор.

если equals () равно

1.Не static и Final, что это.

2.Ссылка из базового класса (подробнее об этом скоро).

затем компилятор откладывает, какой метод вызывается в JVM. Точный метод, который вызывается, зависит от Динамического Типа(более скоро) переменной, которая вызывает метод. В нашем случае переменной является тип. Это называется вызовом динамического метода.

теперь ссылка из базового класса: Из приведенного выше кода

Object typ = new Types();
typ.equals("Hi");

объект типа можно рассматривать как базовый тип типа, также известный как Статического Типа ссылочной переменной и equals () ссылаются из базового типа, в данном случае Object.

если бы у нас было

Types typ = new Types();

не было бы никакой ссылки от базы тип и, следовательно, нет вызова динамического метода.

теперь Динамического Типа переменной ссылку.

Object typ = new Types();
typ.equals("Hi");

на Динамического Типа typ-это типы, и в соответствии с вызовом динамического метода equals () в типах классов вызывается во время выполнения.

также предположим, что у нас был другой класс, который расширяет типы, TypesSubClass. И TypesSubClass также имел переопределенные equals (). Тогда

Object typ = new TypesSubClass();
typ.equals("Hi");

сделали бы the Динамического Типа типа TypesSubClass и TypesSubClass equals () будет вызываться во время выполнения.

честно говоря, я лично не знал, зачем нам все это нужно, и разместил вопрос об этом. проверка

в чем причина динамическое разрешение метода в staticlly типизированный язык, как Java


вы должны взглянуть на эту статью: http://www.sitepoint.com/typing-versus-dynamic-typing/

статическая типизация-это когда язык не требует инициализации переменной.

например.

/* C code */ 
static int num, sum; // explicit declaration 
num = 5; // now use the variables 
sum = 10; 
sum = sum + num;

динамическая типизация-это когда язык требует инициализации переменной.

например.

/* Python code */ 
num = 10 // directly using the variable