Разница между динамическими и статическими назначениями типов в 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
, тип, который он имел во время компиляции.
тип ссылок на объекты a, b, g и f определяется во время компиляции. Они статически типизированы и не изменяются во время выполнения.
тип объекта, созданного с
new
также определяется во время компиляции. Они также статически типизированы и не изменяются во время выполнения.объекты, объект 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