Instructor: James Riely
typedef struct Node Node;
struct Node {
int *item;
Node *next;
};
int *get_last (Node *xs) {
while (xs->next != NULL) {
xs = xs->next;
}
return xs->item;
}
(void *)
type in C
typedef struct Node Node;
struct Node {
void *item;
Node *next;
};
void *get_last (Node *xs) {
while (xs->next != NULL) {
xs = xs->next;
}
return xs->item;
}
typedef struct Node Node;
struct Node {
void *item;
Node *next;
};
int main () {
int *p = (int *) malloc (sizeof(int));
*p = 2123456789;
Node *xs = (Node *) malloc (sizeof(Node));
xs->next = NULL;
xs->item = p; // store int pointer
double *q = get_last(xs); // alias of p
printf ("q=%f\n", *q); // unsafe access
}
$ clang -m32 parametric-03.c && ./a.out
q=96621069057346178268049192388430659584.000000
static class Node {
Integer item;
Node next;
}
static Integer getLast (Node xs) {
while (xs.next != null) {
xs = xs.next;
}
return xs.item;
}
static class Node {
Object item;
Node next;
}
static Object getLast (Node xs) {
while (xs.next != null) {
xs = xs.next;
}
return xs.item;
}
ClassCastException
better than unsafe access
static class Node {
Object item;
Node next;
}
public static void main (String[] args) {
Integer p = Integer.valueOf(2123456789);
Node xs = new Node();
xs.next = null;
xs.item = p; // store Integer
Double q = (Double) getLast(xs); // ClassCastException
System.out.printf ("d=%f\n", q); // unsafe access
}
$ javac Parametric2.java
$ java Parametric2
java.lang.ClassCastException: Integer cannot be cast to Double
at Parametric.main(Parametric2.java:10)
static Node<X> {
X item;
Node<X> next;
}
static <X> X getLast (Node<X> xs) {
while (xs.next != null) {
xs = xs.next;
}
return xs.item;
}
static class Node<X> {
X item;
Node<X> next;
}
public static void main (String[] args) {
Integer p = Integer.valueOf(2123456789);
Node<Integer> xs = new Node<>();
xs.next = null;
xs.item = p; // store Integer
Double q = (Double) getLast(xs); // compiler error
System.out.printf ("d=%f\n", q); // unsafe access
}
$ javac Parametric1.java
error: incompatible types: Integer cannot be converted to Double
Double q = (Double) getLast(xs); // compiler error
^
static class ArrayList<X> {
X[] a;
ArrayList(int n) {
a = new X[n];
}
void put (int i, X item) { a[i] = item; }
X get (int i) { return a[i]; }
}
$ javac Parametric3.java
error: generic array creation
a = new X[n];
^
static class ArrayList<X> {
X[] a;
ArrayList(int n) {
a = (X[]) new Object[n];
}
void put (int i, X item) { a[i] = item; }
X get (int i) { return a[i]; }
}
$ javac -Xlint:unchecked Parametric4.java
warning: [unchecked] unchecked cast
a = (X[]) new Object[n];
^
static class ArrayList<X> {
X[] a;
@SuppressWarnings("unchecked")
ArrayList(int n) {
a = (X[]) new Object[n];
}
void put (int i, X item) { a[i] = item; }
X get (int i) { return a[i]; }
}
$ javac -Xlint:unchecked Parametric4.java
// works fine
ArrayList<String> ss = new ArrayList<>(10);
ArrayList os = ss;
os.put (1, 2123456789);
String s = ss.get (1);
$ javac Parametric6.java
Note: Parametric6.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
$ java Parametric6
ClassCastException: Integer cannot be cast to class String
at Parametric.main(Parametric6.java:4)
String[] ss = new String[10];
Object[] os = ss;
os[1] = 2123456789;
String s = ss[1];
$ javac Parametric7.java
// no warnings
$ java Parametric7
ArrayStoreException: Integer
at Parametric.main(Parametric7.java:3)
List<T>
List<int>
, List<string>