// see also the C++ approximation of this
// that doesn't compile because arrays aren't covariant in C++
public class Covariance
{
public static void main(String[] args)
{
// Review: base = derived is OK, derived = base is not
Integer i = new Integer(13);
Object o = i; // base = derived
System.out.println("hashcode of Integer through Object reference: " + o.hashCode() * 5);
/*
Object o2 = new Object();
Integer i2 = o2; // needs downcast (run-time type check)
System.out.println(i2.intValue() * 5);
*/
String[] officers = {null, null, null};
fillArray(officers, "JRG");
System.out.println("nulls after fill: " + countNulls(officers));
// does this work with array of base = array of derived?
Integer[] primes = { 2, 3, 5, 7, null };
// LEGAL! arrays are covariant
Object[] arr = primes;
// but does covariance make sense? is an Integer[] also an Object[]
// in C++ terms: ptr to (ptr to base) = ptr to (ptr to derived)
// is every ptr to derived also a ptr to base?
// does ptr to derived have same capabilities as ptr to base (plus maybe some more)
// can I do anything to an Integer reference that I can do to an Object ref?
// NO: can assign an object ref to an Object ref but not to an Integer
// (or, in terms of the Java arrays: can put an Object in an Object[]
// but can't put an Object in an Integer[])
// so why does Java have covariance? to allow methods to work
// on generic arrays:
System.out.println("array with nulls: " + countNulls(primes));
// but now this passes compile-time checks; need something to
// prevent disaster (non-existent method) on line AAA
arr[4] = new String("Eleven"); // run-time exception
// (Java arrays know their element type)
System.out.println(primes[4].intValue()); // AAA
Integer[] p2 = copyArray(primes);
// if creating array of generic type was OK, this could end
// in disaster (see attempted implementation of copyArray below)
System.out.println(p2[0].intValue() * p2[1].intValue());
}
public static void fillArray(T[] arr, T elt)
{
for (int i = 0; i < arr.length; i++)
{
arr[i] = elt;
}
}
public static T[] copyArray(T[] arr)
{
return null; // implement copyArray some other way since the below doesn't compile
/**
T[] copy = new T[arr.length]; // can't do this
Object[] alias = copy;
for (int i = 0; i < arr.length; i++)
{
alias[i] = arr[i].toString(); // useless run-time check;
// useless because of type erasure
}
return copy;
*/
}
/*
public static Object[] copyArray(Object[] arr)
{
Object[] copy = new Object[arr.length];
Object[] alias = copy;
for (int i = 0; i < arr.length; i++)
{
alias[i] = arr[i].toString(); // useless run-time check;
// useless because of type erasure
}
return copy;
}
*/
public static int countNulls(Object[] arr)
{
int count = 0;
for (Object o : arr)
{
if (o == null)
{
count++;
}
}
return count;
}
}