что такое casting java

Приведение типов объектов в Java

Обзор приведения типов в Java, покрытый простыми и понятными примерами.

1. Обзор

Система типов Java состоит из двух типов: примитивов и ссылок.

Дальнейшее чтение:

Основы дженериков Java

Оператор Java instanceof

2. Примитивный против Ссылка

В обоих случаях мы “превращаем” один тип в другой. Но, упрощенно говоря, примитивная переменная содержит свое значение, и преобразование примитивной переменной означает необратимые изменения ее значения:

Ссылочные переменные различны ; ссылочная переменная ссылается только на объект, но не содержит самого объекта.

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

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

3. Апкастинг

Апкастинг тесно связан с наследованием – еще одной основной концепцией в Java. Обычно ссылочные переменные используются для ссылки на более конкретный тип. И каждый раз, когда мы это делаем, происходит скрытое повышение.

Чтобы продемонстрировать восходящее вещание, давайте определим класс Animal :

Теперь давайте расширим Животное :

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

И мы также можем назначить его ссылочной переменной типа Animal :

В приведенном выше задании имеет место неявное повышение. Мы могли бы сделать это явно:

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

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

Хотя Cat объект остается Cat объектом, вызов meow() вызовет ошибку компилятора:

Но теперь мы опишем, что дает нам это предсказание. Благодаря апкастингу мы можем воспользоваться преимуществами полиморфизма.

3.1. Полиморфизм

Неявная передача происходит, когда мы добавляем объекты определенного типа в список animals :

Также распространена передача на интерфейс.

Мы можем создать Новый интерфейс и сделать Cat реализовать его:

Теперь любой объект Cat также может быть передан в Mew :

Это/| Кошка является Новым , Животным , Объектом и Кошкой . В нашем примере он может быть назначен ссылочным переменным всех четырех типов.

3.2. Переопределение

Если мы добавим некоторые записи в наши классы, мы увидим, что вызываются методы Cat ‘и Dog :

4. Даункастинг

Давайте возьмем пример:

Чтобы вызвать мяу() мы должны опустить животное к Кошке :

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

Давайте перепишем предыдущий пример Animal Feeder с помощью метода meow() :

4.1. Оператор instanceof

Мы часто используем оператор instanceof перед понижением, чтобы проверить, принадлежит ли объект определенному типу:

4.2. Исключение ClassCastException

Чтобы продемонстрировать это, давайте удалим оператор instanceof из приведенного выше кода:

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

ява,ланг.ClassCastException: com.baeldung.casting.Собака не может быть брошена в com.baeldung.casting.Cat

ClassCastException’ s всегда выбрасывается во время выполнения, если тип, к которому мы относимся, не соответствует типу реального объекта.

Обратите внимание, что если мы попытаемся перейти к несвязанному типу, компилятор этого не допустит:

Компилятор говорит: “Не может привести от животного к строке”.

Для компиляции кода оба типа должны находиться в одном дереве наследования.

Давайте подведем итоги:

5. метод cast()

Есть еще один способ приведения объектов с помощью методов Class :

В приведенном выше примере вместо операторов cast и instanceof используются методы cast ( ) и isInstance () соответственно.

Обычно используются методы cast() и isInstance() с универсальными типами.

Давайте создадим AnimalFeederGeneric класс с feed() методом, который “кормит” только один тип животных – кошек или собак, в зависимости от значения параметра типа:

Давайте сделаем T равным Cat и убедимся, что метод возвращает только кошек:

6. Заключение

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

Источник

Elwood’s blog

Написал я тут обобщённый метод, который выглядит так:

String str = (String) this.getParamValue(); // this.getParamValue() возвращает Object

Так всё и работает. Поэтому в принципе не так уж и важно, правильно ли компилятор выведет тип при вызове getParamValue(). В любом случае будет вызов метода, возвращающего Object, и последующий каст к конкретному типу переменной (поля, аргумента функции).

Примитивные типы обрабатываются несколько особым образом. Допустим, мы вызываем наш метод и пытаемся присводить результат переменной-примитиву:

Кажется, что здесь может потребоваться явное указание типа T, так как long не может выступать в качестве типа-аргумента, однако компилятор достаточно умён и выполнит вывод ссылочного типа Long, соответствующего примитивному типу long, автоматически, и ещё добавит анбоксинг:

Осталось рассмотреть предупреждение компилятора “Unchecked cast: X to Y”, которое выдается при компиляции кода, преобразующего Object в обобщённый тип, либо в тип, зависящий от обобщённого типа:

List list = (List ) map.get(«list»);

Теперь нам понятно, почему компилятор выдаёт это предупреждение. Инструкция checkcast добавляется в сгенерированный байткод, но она проверяет только то, что объект является списком List. Но то, что этот список был создан с типом-аргументом String, эта инструкция проверить не может. Аналогичное предупреждение мы получаем в строчке

return ( T ) joinPoint.getArgs()[index];

– и тут компилятор вообще ничем не может нам помочь, поскольку информация о T будет недоступна во время выполнения, переменная будет иметь тип Object, и мы не сможем быть уверены, что там хранится объект типа T, а не что-либо другое.

Источник

Что такое casting java

short to byte or char

char to byte or short

A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range.

A narrowing conversion of a floating-point number to an integral type T takes two steps:

Otherwise, one of the following two cases must be true:

In the second step:

Example 5.1.3-1. Narrowing Primitive Conversion

This program produces the output:

Despite the fact that overflow, underflow, or other loss of information may occur, a narrowing primitive conversion never results in a run-time exception (§11.1.1).

Example 5.1.3-2. Narrowing Primitive Conversions that lose information

This program produces the output:

5.1.4. Widening and Narrowing Primitive Conversion

The following conversion combines both widening and narrowing primitive conversions:

First, the byte is converted to an int via widening primitive conversion (§5.1.2), and then the resulting int is converted to a char by narrowing primitive conversion (§5.1.3).

5.1.5. Widening Reference Conversion

Widening reference conversions never require a special action at run time and therefore never throw an exception at run time. They consist simply in regarding a reference as having some other type in a manner that can be proved correct at compile time.

5.1.6. Narrowing Reference Conversion

Six kinds of conversions are called the narrowing reference conversions :

An important special case is that there is a narrowing reference conversion from the class type Object to any other reference type (§4.12.4).

Such conversions require a test at run time to find out whether the actual reference value is a legitimate value of the new type. If not, then a ClassCastException is thrown.

5.1.7. Boxing Conversion

Boxing conversion converts expressions of primitive type to corresponding expressions of reference type. Specifically, the following nine conversions are called the boxing conversions :

From type boolean to type Boolean

From type byte to type Byte

From type short to type Short

From type char to type Character

From type int to type Integer

From type long to type Long

From type float to type Float

From type double to type Double

From the null type to the null type

Читайте также:  что делать если мерзнешь в тепле

This rule is necessary because the conditional operator (§15.25) applies boxing conversion to the types of its operands, and uses the result in further calculations.

At run time, boxing conversion proceeds as follows:

If p is a value of type float then:

If p is a value of any other type, boxing conversion is equivalent to an identity conversion (§5.1.1).

5.1.8. Unboxing Conversion

Unboxing conversion converts expressions of reference type to corresponding expressions of primitive type. Specifically, the following eight conversions are called the unboxing conversions :

From type Boolean to type boolean

From type Byte to type byte

From type Short to type short

From type Character to type char

From type Integer to type int

From type Long to type long

From type Float to type float

From type Double to type double

At run time, unboxing conversion proceeds as follows:

A type is said to be convertible to a numeric type if it is a numeric type (§4.2), or it is a reference type that may be converted to a numeric type by unboxing conversion.

A type is said to be convertible to an integral type if it is an integral type, or it is a reference type that may be converted to an integral type by unboxing conversion.

5.1.9. Unchecked Conversion

Let G name a generic type declaration with n type parameters.

Unchecked conversion is used to enable a smooth interoperation of legacy code, written before the introduction of generic types, with libraries that have undergone a conversion to use genericity (a process we call generification). In such circumstances (most notably, clients of the Collections Framework in java.util ), legacy code uses raw types (e.g. Collection instead of Collection ). Expressions of raw types are passed as arguments to library methods that use parameterized versions of those same types as the types of their corresponding formal parameters.

Such calls cannot be shown to be statically safe under the type system using generics. Rejecting such calls would invalidate large bodies of existing code, and prevent them from using newer versions of the libraries. This in turn, would discourage library vendors from taking advantage of genericity. To prevent such an unwelcome turn of events, a raw type may be converted to an arbitrary invocation of the generic type declaration to which the raw type refers. While the conversion is unsound, it is tolerated as a concession to practicality. An unchecked warning is issued in such cases.

5.1.10. Capture Conversion

Capture conversion on any type other than a parameterized type (§4.5) acts as an identity conversion (§5.1.1).

Capture conversion is not applied recursively.

Capture conversion never requires a special action at run time and therefore never throws an exception at run time.

Capture conversion is designed to make wildcards more useful. To understand the motivation, let’s begin by looking at the method java.util.Collections.reverse() :

The method reverses the list provided as a parameter. It works for any type of list, and so the use of the wildcard type List as the type of the formal parameter is entirely appropriate.

Now consider how one would implement reverse() :

the following code would undermine the type system:

So, without some special dispensation, we can see that the call from reverse() to rev() would be disallowed. If this were the case, the author of reverse() would be forced to write its signature as:

This is undesirable, as it exposes implementation information to the caller. Worse, the designer of an API might reason that the signature using a wildcard is what the callers of the API require, and only later realize that a type safe implementation was precluded.

The classical open operation on existentials requires that the captured type variable must not escape the opened expression. The open that corresponds to capture conversion is always on a scope sufficiently large that the captured type variable can never be visible outside that scope. The advantage of this scheme is that there is no need for a close operation, as defined in the paper On Variance-Based Subtyping for Parametric Types by Atsushi Igarashi and Mirko Viroli, in the proceedings of the 16th European Conference on Object Oriented Programming (ECOOP 2002). For a formal account of wildcards, see Wild FJ by Mads Torgersen, Erik Ernst and Christian Plesner Hansen, in the 12th workshop on Foundations of Object Oriented Programming (FOOL 2005).

5.1.11. String Conversion

A value x of primitive type T is first converted to a reference value as if by giving it as an argument to an appropriate class instance creation expression (§15.9):

This reference value is then converted to type String by string conversion.

Now only reference values need to be considered:

See §5.4 for details of the string conversion context.

5.1.12. Forbidden Conversions

Any conversion that is not explicitly allowed is forbidden.

5.1.13. Value Set Conversion

Value set conversion is the process of mapping a floating-point value from one value set to another without changing its type.

Within an expression that is not FP-strict (§15.4), value set conversion provides choices to an implementation of the Java programming language:

If the value is an element of the float-extended-exponent value set, then the implementation may, at its option, map the value to the nearest element of the float value set. This conversion may result in overflow (in which case the value is replaced by an infinity of the same sign) or underflow (in which case the value may lose precision because it is replaced by a denormalized number or zero of the same sign).

If the value is an element of the double-extended-exponent value set, then the implementation may, at its option, map the value to the nearest element of the double value set. This conversion may result in overflow (in which case the value is replaced by an infinity of the same sign) or underflow (in which case the value may lose precision because it is replaced by a denormalized number or zero of the same sign).

Within an FP-strict expression (§15.4), value set conversion does not provide any choices; every implementation must behave in the same way:

If the value is of type float and is not an element of the float value set, then the implementation must map the value to the nearest element of the float value set. This conversion may result in overflow or underflow.

If the value is of type double and is not an element of the double value set, then the implementation must map the value to the nearest element of the double value set. This conversion may result in overflow or underflow.

Within an FP-strict expression, mapping values from the float-extended-exponent value set or double-extended-exponent value set is necessary only when a method is invoked whose declaration is not FP-strict and the implementation has chosen to represent the result of the method invocation as an element of an extended-exponent value set.

5.2. Assignment Conversion

Assignment conversion occurs when the value of an expression is assigned (§15.26) to a variable: the type of the expression must be converted to the type of the variable.

Assignment contexts allow the use of one of the following:

an identity conversion (§5.1.1)

a widening primitive conversion (§5.1.2)

a widening reference conversion (§5.1.5)

a boxing conversion (§5.1.7) optionally followed by a widening reference conversion

an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

Читайте также:  что делать если переел сладкого и болит живот

If, after the conversions listed above have been applied, the resulting type is a raw type (§4.8), unchecked conversion (§5.1.9) may then be applied.

It is a compile-time error if the chain of conversions contains two parameterized types that are not in the subtype relation.

An example of such an illegal chain would be:

A narrowing primitive conversion followed by a boxing conversion may be used if the type of the variable is:

The compile-time narrowing of constants means that code such as:

is allowed. Without the narrowing, the fact that the integer literal 42 has type int would mean that a cast to byte would be required:

A value of the null type (the null reference is the only such value) may be assigned to any reference type, resulting in a null reference of that type.

If the type of the expression cannot be converted to the type of the variable by a conversion permitted in an assignment context, then a compile-time error occurs.

If the type of an expression can be converted to the type of a variable by assignment conversion, we say the expression (or its value) is assignable to the variable or, equivalently, that the type of the expression is assignment compatible with the type of the variable.

If v is of type float and is an element of the float-extended-exponent value set, then the implementation must map v to the nearest element of the float value set. This conversion may result in overflow or underflow.

If v is of type double and is an element of the double-extended-exponent value set, then the implementation must map v to the nearest element of the double value set. This conversion may result in overflow or underflow.

The only exceptions that an assignment conversion may cause are:

A ClassCastException if, after the type conversions above have been applied, the resulting value is an object which is not an instance of a subclass or subinterface of the erasure (§4.6) of the type of the variable.

This circumstance can only arise as a result of heap pollution (§4.12.2). In practice, implementations need only perform casts when accessing a field or method of an object of parametized type, when the erased type of the field, or the erased result type of the method differ from their unerased type.

An OutOfMemoryError as a result of a boxing conversion.

A NullPointerException as a result of an unboxing conversion on a null reference.

An ArrayStoreException in special cases involving array elements or field access (§10.5, §15.26.1).

Example 5.2-1. Assignment Conversion for Primitive Types

This program produces the output:

The following program, however, produces compile-time errors:

because not all short values are char values, and neither are all char values short values.

Example 5.2-2. Assignment Conversion for Reference Types

The following test program illustrates assignment conversions on reference values, but fails to compile, as described in its comments. This example should be compared to the preceding one.

Example 5.2-3. Assignment Conversion for Array Types

5.3. Method Invocation Conversion

Method invocation conversion is applied to each argument value in a method or constructor invocation (§8.8.7.1, §15.9, §15.12): the type of the argument expression must be converted to the type of the corresponding parameter.

Method invocation contexts allow the use of one of the following:

an identity conversion (§5.1.1)

a widening primitive conversion (§5.1.2)

a widening reference conversion (§5.1.5)

a boxing conversion (§5.1.7) optionally followed by widening reference conversion

an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

If, after the conversions listed above have been applied, the resulting type is a raw type (§4.8), an unchecked conversion (§5.1.9) may then be applied.

It is a compile-time error if the chain of conversions contains two parameterized types that are not in the subtype relation.

A value of the null type (the null reference is the only such value) may be converted to any reference type.

If the type of the expression cannot be converted to the type of the parameter by a conversion permitted in a method invocation context, then a compile-time error occurs.

If an argument value of type float is an element of the float-extended-exponent value set, then the implementation must map the value to the nearest element of the float value set. This conversion may result in overflow or underflow.

If an argument value of type double is an element of the double-extended-exponent value set, then the implementation must map the value to the nearest element of the double value set. This conversion may result in overflow or underflow.

The only exceptions that an method invocation conversion may cause are:

A ClassCastException if, after the type conversions above have been applied, the resulting value is an object which is not an instance of a subclass or subinterface of the erasure (§4.6) of the corresponding formal parameter type.

This circumstance can only arise as a result of heap pollution (§4.12.2).

An OutOfMemoryError as a result of a boxing conversion.

A NullPointerException as a result of an unboxing conversion on a null reference.

Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion (§5.2). The designers of the Java programming language felt that including these implicit narrowing conversions would add additional complexity to the overloaded method matching resolution process (§15.12.2).

5.4. String Conversion

In this single special case, the non- String operand to the + is converted to a String (§5.1.11) and evaluation of the + operator proceeds as specified in §15.18.1.

5.5. Casting Conversion

Casting conversion is applied to the operand of a cast operator (§15.16): the type of the operand expression must be converted to the type explicitly named by the cast operator.

Casting contexts allow the use of one of:

an identity conversion (§5.1.1)

a widening primitive conversion (§5.1.2)

a narrowing primitive conversion (§5.1.3)

a widening and narrowing primitive conversion (§5.1.4)

a widening reference conversion (§5.1.5) optionally followed by either an unboxing conversion (§5.1.8) or an unchecked conversion (§5.1.9)

a narrowing reference conversion (§5.1.6) optionally followed by either an unboxing conversion (§5.1.8) or an unchecked conversion (§5.1.9)

a boxing conversion (§5.1.7) optionally followed by a widening reference conversion (§5.1.5)

an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion (§5.1.2).

Value set conversion (§5.1.13) is applied after the type conversion.

The compile-time legality of a casting conversion is as follows:

An expression of a primitive type may undergo casting conversion to another primitive type, by an identity conversion (if the types are the same), or by a widening primitive conversion, or by a narrowing primitive conversion, or by a widening and narrowing primitive conversion.

An expression of a primitive type may undergo casting conversion to a reference type without error, by boxing conversion.

An expression of a reference type may undergo casting conversion to a primitive type without error, by unboxing conversion.

An expression of a reference type may undergo casting conversion to another reference type if no compile-time error occurs given the rules in §5.5.1.

The following tables enumerate which conversions are used in certain casting conversions. Each conversion is signified by a symbol:

— signifies no casting conversion allowed

≈ signifies identity conversion (§5.1.1)

ω signifies widening primitive conversion (§5.1.2)

η signifies narrowing primitive conversion (§5.1.3)

ωη signifies widening and narrowing primitive conversion (§5.1.4)

⇑ signifies widening reference conversion (§5.1.5)

⇓ signifies narrowing reference conversion (§5.1.6)

⊡ signifies boxing conversion (§5.1.7)

⊔ signifies unboxing conversion (§5.1.8)

Table 5.1. Casting conversions to primitive types

To → byte short char int long float double boolean
From ↓
byte ω ωη ω ω ω ω
short η η ω ω ω ω
char η η ω ω ω ω
int η η η ω ω ω
long η η η η ω ω
float η η η η η ω
double η η η η η η
boolean
Byte ⊔,ω ⊔,ω ⊔,ω ⊔,ω ⊔,ω
Short ⊔,ω ⊔,ω ⊔,ω ⊔,ω
Character ⊔,ω ⊔,ω ⊔,ω ⊔,ω
Integer ⊔,ω ⊔,ω ⊔,ω
Long ⊔,ω ⊔,ω
Float ⊔,ω
Double
Boolean
Object ⇓,⊔ ⇓,⊔ ⇓,⊔ ⇓,⊔ ⇓,⊔ ⇓,⊔ ⇓,⊔ ⇓,⊔

Table 5.2. Casting conversions to reference types

To → Byte Short Character Integer Long Float Double Boolean Object
From ↓
byte ⊡,⇑
short ⊡,⇑
char ⊡,⇑
int ⊡,⇑
long ⊡,⇑
float ⊡,⇑
double ⊡,⇑
boolean ⊡,⇑
Byte
Short
Character
Integer
Long
Float
Double
Boolean
Object

5.5.1. Reference Type Casting

Given a compile-time reference type S (source) and a compile-time reference type T (target), a casting conversion exists from S to T if no compile-time errors occur due to the following rules.

If S is a class type:

If T is a class type, then either | S | | T |, or | T | | S |. Otherwise, a compile-time error occurs.

If T is an interface type:

If S is an interface type:

If T is an array type, then S must be the type java.io.Serializable or Cloneable (the only interfaces implemented by arrays), or a compile-time error occurs.

Furthermore, if S and X are provably distinct parameterized types then a compile-time error occurs.

If T is an interface type, then a compile-time error occurs unless T is the type java.io.Serializable or the type Cloneable (the only interfaces implemented by arrays).

If T is a type variable, then:

Otherwise, a compile-time error occurs.

TC and SC are the same primitive type.

Example 5.5.1-1. Casting Conversion for Reference Types

Here, the first compile-time error occurs because the class types Long and Point are unrelated (that is, they are not the same, and neither is a subclass of the other), so a cast between them will always fail.

Example 5.5.1-2. Casting Conversion for Array Types

This program compiles without errors and produces the output:

5.5.2. Checked Casts and Unchecked Casts

A cast from a type S to a type T is statically known to be correct if and only if S T (§4.10).

A cast from a type S to a parameterized type (§4.5) T is unchecked unless at least one of the following conditions holds:

All of the type arguments (§4.5.1) of T are unbounded wildcards

An unchecked cast causes a compile-time unchecked warning, unless suppressed by the SuppressWarnings annotation (§9.6.3.5).

A cast is checked if it is not statically known to be correct and it is not unchecked.

If a cast to a reference type is not a compile-time error, there are several cases:

The cast is statically known to be correct.

No run-time action is performed for such a cast.

The cast is a completely unchecked cast.

No run-time action is performed for such a cast.

The cast is a partially unchecked cast.

Such a cast requires a run-time validity check. The check is performed as if the cast had been a checked cast between | S | and | T |, as described below.

The cast is a checked cast.

Note that R cannot be an interface when these rules are first applied for any given cast, but R may be an interface if the rules are applied recursively because the run-time reference value may refer to an array whose element type is an interface type.

5.5.3. Checked Casts at Run Time

If R is an ordinary class (not an array class):

If T is an array type, then a run-time exception is thrown.

If R is an interface:

If T is a class type, then T must be Object (§4.3.2), or a run-time exception is thrown.

If T is an array type, then a run-time exception is thrown.

If T is a class type, then T must be Object (§4.3.2), or a run-time exception is thrown.

If T is an interface type, then a run-time exception is thrown unless T is the type java.io.Serializable or the type Cloneable (the only interfaces implemented by arrays).

TC and RC are the same primitive type.

TC and RC are reference types and type RC can be cast to TC by a recursive application of these run-time rules for casting.

Example 5.5.3-1. Incompatible Types at Run Time

This program uses casts to compile, but it throws exceptions at run time, because the types are incompatible.

5.6. Numeric Promotions

Numeric promotion is applied to the operands of an arithmetic operator.

Numeric promotion contexts allow the use of:

an identity conversion (§5.1.1)

a widening primitive conversion (§5.1.2)

an unboxing conversion (§5.1.8)

Numeric promotions are used to convert the operands of a numeric operator to a common type so that an operation can be performed. The two kinds of numeric promotion are unary numeric promotion (§5.6.1) and binary numeric promotion (§5.6.2).

5.6.1. Unary Numeric Promotion

Some operators apply unary numeric promotion to a single operand, which must produce a value of a numeric type:

Otherwise, a unary numeric operand remains as is and is not converted.

In any case, value set conversion (§5.1.13) is then applied.

Unary numeric promotion is performed on expressions in the following situations:

Each dimension expression in an array creation expression (§15.10)

The index expression in an array access expression (§15.13)

The operand of a unary plus operator + (§15.15.3)

The operand of a bitwise complement operator

Example 5.6.1-1. Unary Numeric Promotion

This program produces the output:

5.6.2. Binary Numeric Promotion

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

After the type conversion, if any, value set conversion (§5.1.13) is applied to each operand.

Binary numeric promotion is performed on the operands of certain operators:

Example 5.6.2-1. Binary Numeric Promotion

This program produces the output:

The example converts the ASCII character G to the ASCII control-G (BEL), by masking off all but the low 5 bits of the character. The 7 is the numeric value of this control character.

Источник

Читайте также:  что делать при онемении головы
Строительный портал