Java Long Assignment

/*

  Java Long Example

  This example shows how an object of Long can be declared and used.

  Long is a wrapper class provided to wrap long primitive value. It has a single

  field of type long.

*/

 

publicclassLongExample{

 

  publicstaticvoidmain(String[]args){

    //create a Long object using one the below given constructors

    //1. Create a Long object from long

    longl=10;

    LonglongObj1=newLong(l);

  

    /*

    2. Create a Long object from String. Please note that this method can

    throw NumberFormatException if string doesnt contain parsable number.

    */

    LonglongObj2=newLong("5");

  

    //print value of Long objects

    System.out.println(longObj1);

    System.out.println(longObj2);

  }

}

 

 

/*

Output of the program would be

10

5

*/

Every expression written in the Java programming language has a type that can be deduced from the structure of the expression and the types of the literals, variables, and methods mentioned in the expression. It is possible, however, to write an expression in a context where the type of the expression is not appropriate. In some cases, this leads to an error at compile time. In other cases, the context may be able to accept a type that is related to the type of the expression; as a convenience, rather than requiring the programmer to indicate a type conversion explicitly, the Java programming language performs an implicit conversion from the type of the expression to a type acceptable for its surrounding context.

A specific conversion from type S to type T allows an expression of type S to be treated at compile time as if it had type T instead. In some cases this will require a corresponding action at run time to check the validity of the conversion or to translate the run-time value of the expression into a form appropriate for the new type T.

In every conversion context, only certain specific conversions are permitted. For convenience of description, the specific conversions that are possible in the Java programming language are grouped into several broad categories:

There are five conversion contexts in which conversion of expressions may occur. Each context allows conversions in some of the categories named above but not others. The term "conversion" is also used to describe the process of choosing a specific conversion for such a context. For example, we say that an expression that is an actual argument in a method invocation is subject to "method invocation conversion," meaning that a specific conversion will be implicitly chosen for that expression according to the rules for the method invocation argument context.

One conversion context is the operand of a numeric operator such as or . The conversion process for such operands is called numeric promotion. Promotion is special in that, in the case of binary operators, the conversion chosen for one operand may depend in part on the type of the other operand expression.

This chapter first describes the eleven categories of conversions (§5.1), including the special conversions to allowed for the string concatenation operator (§15.18.1). Then the five conversion contexts are described:

Specific type conversions in the Java programming language are divided into 13 categories.

A conversion from a type to that same type is permitted for any type.

This may seem trivial, but it has two practical consequences. First, it is always permitted for an expression to have the desired type to begin with, thus allowing the simply stated rule that every expression is subject to conversion, if only a trivial identity conversion. Second, it implies that it is permitted for a program to include redundant cast operators for the sake of clarity.

5.1.1. Identity Conversion

19 specific conversions on primitive types are called the widening primitive conversions:

  • to , , , , or

  • to , , , or

  • to , , , or

  • to , , or

  • to or

  • to

A widening primitive conversion does not lose information about the overall magnitude of a numeric value.

A widening primitive conversion from an integral type to another integral type, or from to in a expression (§15.4), does not lose any information at all; the numeric value is preserved exactly.

A widening primitive conversion from to that is not may lose information about the overall magnitude of the converted value.

A widening conversion of an or a value to , or of a value to , may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).

A widening conversion of a signed integer value to an integral type T simply sign-extends the two's-complement representation of the integer value to fill the wider format.

A widening conversion of a to an integral type T zero-extends the representation of the value to fill the wider format.

Despite the fact that loss of precision may occur, a widening primitive conversion never results in a run-time exception (§11.1.1).

Example 5.1.2-1. Widening Primitive Conversion

class Test { public static void main(String[] args) { int big = 1234567890; float approx = big; System.out.println(big - (int)approx); } }

This program prints:

-46

thus indicating that information was lost during the conversion from type to type because values of type are not precise to nine significant digits.


5.1.2. Widening Primitive Conversion

22 specific conversions on primitive types are called the narrowing primitive conversions:

  • to or

  • to or

  • to , , or

  • to , , , or

  • to , , , , or

  • to , , , , , or

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

A narrowing primitive conversion from to is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a zero from a nonzero and a infinity from a finite . A NaN is converted to a NaN and a infinity is converted to the same-signed infinity.

A narrowing conversion of a signed integer to an integral type T simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the sign of the resulting value to differ from the sign of the input value.

A narrowing conversion of a to an integral type T likewise simply discards all but the n lowest order bits, where n is the number of bits used to represent type T. In addition to a possible loss of information about the magnitude of the numeric value, this may cause the resulting value to be a negative number, even though chars represent 16-bit unsigned integer values.

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

  1. In the first step, the floating-point number is converted either to a , if T is , or to an , if T is , , , or , as follows:

    • If the floating-point number is NaN (§4.2.3), the result of the first step of the conversion is an or .

    • Otherwise, if the floating-point number is not an infinity, the floating-point value is rounded to an integer value , rounding toward zero using IEEE 754 round-toward-zero mode (§4.2.3). Then there are two cases:

      1. If T is , and this integer value can be represented as a , then the result of the first step is the value .

      2. Otherwise, if this integer value can be represented as an , then the result of the first step is the value .

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

      1. The value must be too small (a negative value of large magnitude or negative infinity), and the result of the first step is the smallest representable value of type or .

      2. The value must be too large (a positive value of large magnitude or positive infinity), and the result of the first step is the largest representable value of type or .

  2. In the second step:

    • If T is or , the result of the conversion is the result of the first step.

    • If T is , , or , the result of the conversion is the result of a narrowing conversion to type T (§5.1.3) of the result of the first step.

Example 5.1.3-1. Narrowing Primitive Conversion

class Test { public static void main(String[] args) { float fmin = Float.NEGATIVE_INFINITY; float fmax = Float.POSITIVE_INFINITY; System.out.println("long: " + (long)fmin + ".." + (long)fmax); System.out.println("int: " + (int)fmin + ".." + (int)fmax); System.out.println("short: " + (short)fmin + ".." + (short)fmax); System.out.println("char: " + (int)(char)fmin + ".." + (int)(char)fmax); System.out.println("byte: " + (byte)fmin + ".." + (byte)fmax); } }

This program produces the output:

long: -9223372036854775808..9223372036854775807 int: -2147483648..2147483647 short: 0..-1 char: 0..65535 byte: 0..-1

The results for , , and are unsurprising, producing the minimum and maximum representable values of the type.

The results for and lose information about the sign and magnitude of the numeric values and also lose precision. The results can be understood by examining the low order bits of the minimum and maximum . The minimum is, in hexadecimal, , and the maximum int is . This explains the results, which are the low 16 bits of these values, namely, and ; it explains the char results, which also are the low 16 bits of these values, namely, and ; and it explains the byte results, which are the low 8 bits of these values, namely, and .


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

class Test { public static void main(String[] args) { // A narrowing of int to short loses high bits: System.out.println("(short)0x12345678==0x" + Integer.toHexString((short)0x12345678)); // An int value too big for byte changes sign and magnitude: System.out.println("(byte)255==" + (byte)255); // A float value too big to fit gives largest int value: System.out.println("(int)1e20f==" + (int)1e20f); // A NaN converted to int yields zero: System.out.println("(int)NaN==" + (int)Float.NaN); // A double value too large for float yields infinity: System.out.println("(float)-1e100==" + (float)-1e100); // A double value too small for float underflows to zero: System.out.println("(float)1e-50==" + (float)1e-50); } }

This program produces the output:

(short)0x12345678==0x5678 (byte)255==-1 (int)1e20f==2147483647 (int)NaN==0 (float)-1e100==-Infinity (float)1e-50==0.0

5.1.3. Narrowing Primitive Conversion

The following conversion combines both widening and narrowing primitive conversions:

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

5.1.4. Widening and Narrowing Primitive Conversion

A widening reference conversion exists from any reference type S to any reference type T, provided S is a subtype (§4.10) of T.

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.5. Widening Reference Conversion

Six kinds of conversions are called the narrowing reference conversions:

  • From any reference type S to any reference type T, provided that S is a proper supertype of T (§4.10).

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

  • From any class type C to any non-parameterized interface type K, provided that C is not and does not implement K.

  • From any interface type J to any non-parameterized class type C that is not .

  • From any interface type J to any non-parameterized interface type K, provided that J is not a subinterface of K.

  • From the interface types and to any array type T.

  • From any array type SC to any array type TC, provided that SC and TC are reference types and there is a narrowing reference conversion from SC to TC.

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 is thrown.

5.1.6. Narrowing Reference 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 to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • 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 is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type , then boxing conversion converts into a reference of class and type , such that

  • If is a value of type then:

    • If is not NaN, then boxing conversion converts into a reference of class and type , such that evaluates to

    • Otherwise, boxing conversion converts into a reference of class and type such that evaluates to

  • If is a value of type , then:

    • If is not NaN, boxing conversion converts into a reference of class and type , such that evaluates to

    • Otherwise, boxing conversion converts into a reference of class and type such that evaluates to

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

If the value being boxed is , , a , or a in the range to , or an or number between and (inclusive), then let and be the results of any two boxing conversions of . It is always the case that .

Ideally, boxing a given primitive value , would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly. For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all and values, as well as and values in the range of -32K to +32K.

A boxing conversion may result in an if a new instance of one of the wrapper classes (, , , , , , , or ) needs to be allocated and insufficient storage is available.

5.1.7. Boxing 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 to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

  • From type to type

At run time, unboxing conversion proceeds as follows:

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is a reference of type , unboxing conversion converts into

  • If is a reference of type , then unboxing conversion converts into

  • If is , unboxing conversion throws a

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.8. Unboxing Conversion

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

There is an unchecked conversion from the raw class or interface type (§4.8) G to any parameterized type of the form GT1,...,Tn.

There is an unchecked conversion from the raw array type G to any array type type of the form GT1,...,Tn.

Use of an unchecked conversion causes a compile-time unchecked warning unless G... is a parameterized type in which all type arguments are unbounded wildcards (§4.5.1), or the unchecked warning is suppressed by the annotation (§9.6.3.5).

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 ), legacy code uses raw types (e.g. instead of ). 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.9. Unchecked Conversion

Let G name a generic type declaration (§8.1.2, §9.1.2) with n type parameters A1,...,An with corresponding bounds U1,...,Un.

There exists a capture conversion from a parameterized type GT1,...,Tn (§4.5) to a parameterized type GS1,...,Sn, where, for 1 ≤ in :

  • If Ti is a wildcard type argument (§4.5.1) of the form , then Si is a fresh type variable whose upper bound is Ui and whose lower bound is the null type (§4.1).

  • If Ti is a wildcard type argument of the form Bi, then Si is a fresh type variable whose upper bound is glb(Bi, Ui) and whose lower bound is the null type.

    glb(V1,...,Vm) is defined as V1 ... Vm.

    It is a compile-time error if, for any two classes (not interfaces) Vi and Vj, Vi is not a subclass of Vj or vice versa.

  • If Ti is a wildcard type argument of the form Bi, then Si is a fresh type variable whose upper bound is Ui and whose lower bound is Bi.

  • Otherwise, Si = Ti.

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 :

public static void reverse(List<?> list);

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

Now consider how one would implement :

public static void reverse(List<?> list) { rev(list); } private static <T> void rev(List<T> list) { List<T> tmp = new ArrayList<T>(list); for (int i = 0; i < list.size(); i++) { list.set(i, tmp.get(list.size() - i - 1)); } }

The implementation needs to copy the list, extract elements from the copy, and insert them into the original. To do this in a type-safe manner, we need to give a name, , to the element type of the incoming list. We do this in the private service method . This requires us to pass the incoming argument list, of type , as an argument to . In general, is a list of unknown type. It is not a subtype of , for any type T. Allowing such a subtype relation would be unsound. Given the method:

public static <T> void fill(List<T> l, T obj)

the following code would undermine the type system:

List<String> ls = new ArrayList<String>(); List<?> l = ls; Collections.fill(l, new Object()); // not legal - but assume it was! String s = ls.get(0); // ClassCastException - ls contains // Objects, not Strings.

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

public static <T> void reverse(List<T> list)

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 call from to is in fact harmless, but it cannot be justified on the basis of a general subtyping relation between and . The call is harmless, because the incoming argument is doubtless a list of some type (albeit an unknown one). If we can capture this unknown type in a type variable , we can infer to be . That is the essence of capture conversion. The specification of course must cope with complications, like non-trivial (and possibly recursively defined) upper or lower bounds, the presence of multiple arguments etc.

Mathematically sophisticated readers will want to relate capture conversion to established type theory. Readers unfamiliar with type theory can skip this discussion - or else study a suitable text, such as Types and Programming Languages by Benjamin Pierce, and then revisit this section.

Here then is a brief summary of the relationship of capture conversion to established type theoretical notions. Wildcard types are a restricted form of existential types. Capture conversion corresponds loosely to an opening of a value of existential type. A capture conversion of an expression can be thought of as an of in a scope that comprises the top level expression that encloses .

The classical operation on existentials requires that the captured type variable must not escape the opened expression. The 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 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.10. Capture Conversion

Any type may be converted to type by string conversion.

A value 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):

  • If T is , then use .

  • If T is , then use .

  • If T is , , or , then use .

  • If T is , then use .

  • If T is , then use .

  • If T is , then use .

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

Now only reference values need to be considered:

  • If the reference is , it is converted to the string "" (four ASCII characters , , , ).

  • Otherwise, the conversion is performed as if by an invocation of the method of the referenced object with no arguments; but if the result of invoking the method is , then the string "" is used instead.

    The method is defined by the primordial class (§4.3.2). Many classes override it, notably , , , , , , and .

See §5.4 for details of the string conversion context.

5.1.11. String Conversion

Any conversion that is not explicitly allowed is forbidden.

5.1.12. Forbidden Conversions

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

5.1.13. Value Set Conversion

5.1. Kinds of Conversion

0 Thoughts to “Java Long Assignment

Leave a comment

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *