top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Bounded Types in JAVA

+4 votes
302 views

When specifying a type parameter, you can create an upper bound that declares the superclass from which all type arguments must be derived. This is accomplished through the use of an extends clause when specifying the type parameter, as shown here:

<T extends superclass>

This specifies that T can only be replaced by superclass, or subclasses of superclass. Thus, superclass defines an inclusive, upper limit. You can use an upper bound to fix the NumericFns class shown earlier by specifying Number as an upper bound, as shown here:

// In this version of NumericFns, the type argument for T must be either Number, or a class derived from Number.

class NumericFns<T extends Number> {

T num;

// Pass the constructor a reference to a numeric object.

NumericFns(T n) {

num = n;

}

// Return the reciprocal.

double reciprocal() {

return 1 / num.doubleValue();

}

//Return the fractional component.

double fraction() {

return num.doubleValue() - num.intValue();

}

// ...

}

//Demonstrate NumericFns.class BoundsDemo {

public static void main(String args[]) {

NumericFns<Integer> iOb =new NumericFns<Integer>(5);

System.out.println("Reciprocal of iOb is " + iOb.reciprocal());

System.out.println("Fractional component of iOb is " + iOb.fraction());

System.out.println();

NumericFns<Double> dOb =new NumericFns<Double>(5.25);

System.out.println("Reciprocal of dOb is " +

dOb.reciprocal());

System.out.println("Fractional component of dOb is " +

dOb.fraction());

// This won't compile because String is not a subclass of Number.

NumericFns<String> strOb = new NumericFns<String>("Error");}

}

The output is shown here:

Reciprocal of iOb is 0.2

Fractional component of iOb is 0.0

Reciprocal of dOb is 0.19047619047619047

Fractional component of dOb is 0.25

Notice how NumericFns is now declared by this line:

class NumericFns<T extends Number> {

Because the type T is now bounded by Number, the Java compiler knows that all objects of type T can call doubleValue( ) because it is a method declared by Number. This is, by itself,
a major advantage. However, as an added bonus, the bounding of T also prevents nonnumeric NumericFns objects from being created. For example, if you try removing the comments from
the lines at the end of the program, and then try re-compiling, you will receive compile-time errors because String is not a subclass of Number.
Bounded types are especially useful when you need to ensure that one type parameter is compatible with another. For example, consider the following class called Pair, which stores
two objects that must be compatible with each other:

class Pair<T, V extends T> {

T first;

V second;

Pair(T a, V b) {

first = a;

second = b;

}

// ...

}

Notice that Pair uses two type parameters, T and V, and that V extends T. This means that V will either be the same as T or a subclass of T. This ensures that the two arguments to
Pair’s constructor will either be objects of the same type or of related types. For example, the following constructions are valid:

// This is OK because both T and V are Integer.

Pair<Integer, Integer> x = new Pair<Integer, Integer>(1, 2);

// This is OK because Integer is a subclass of Number.

Pair<Number, Integer> y = new Pair<Number, Integer>(10.4, 12);

However, the following is invalid:

// This causes an error because String is not a subclass of Number

Pair<Number, String> z = new Pair<Number, String>(10.4, "12");

In this case, String is not a subclass of Number, which violates the bound specified by Pair.

posted Feb 15, 2016 by Reshmi S

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Although the automatic type conversions are helpful, they will not fulfill all programming needs because they apply only to widening conversions between compatible types. For all other cases you must employ a cast. A cast is an instruction to the compiler to convert one type into another.
Thus, it requests an explicit type conversion. A cast has this general form: (target-type) expression Here, target-type specifies the desired type to convert the specified expression to. For example, if you want to convert the type of the expression x/y to int, you can write

double x, y;
// ...
(int) (x / y)

Here, even though x and y are of type double, the cast converts the outcome of the expression to int. The parentheses surrounding x / y are necessary. Otherwise, the cast to int would apply only to the x and not to the outcome of the division. The cast is necessary here because there is no automatic conversion from double to int.
When a cast involves a narrowing conversion, information might be lost. For example, when casting a long into a short, information will be lost if the long’s value is greater than the range of a short because its high-order bits are removed. When a floating-point value is cast to an integer type, the fractional component will also be lost due to truncation. For example, if the value 1.23 is assigned to an integer, the resulting value will simply be 1. The 0.23 is lost.
The following program demonstrates some type conversions that require casts:

// Demonstrate casting.
class CastDemo {
public static void main(String args[]) {
double x, y;
byte b;
int i;
char ch;
x = 10.0;
y = 3.0;
i = (int) (x / y); // cast double to int
System.out.println("Integer outcome of x / y: " + i);
i = 100;
b = (byte) i;
System.out.println("Value of b: " + b);
i = 257;
b = (byte) i;
System.out.println("Value of b: " + b);
b = 88; // ASCII code for X
ch = (char) b;


The output from the program is shown here:

Integer outcome of x / y: 3
Value of b: 100
Value

In the program, the cast of (x / y) to int results in the truncation of the fractional component, and information is lost. Next, no loss of information occurs when b is assigned the value 100 because a byte can hold the value 100. However, when the attempt is made to assign b the value 257, information loss occurs because 257 exceeds a byte’s maximum value. Finally, no information is lost, but a cast is needed when assigning a byte value to a char.

READ MORE
...