Instructor: James Riely
typedef struct Node Node;
struct Node {
int *head;
Node *tail;
};
int *get_last (Node *xs) {
while (xs->tail != NULL) {
xs = xs->tail;
}
return xs->head;
}
(void *)
type in C
typedef struct Node Node;
struct Node {
void *head;
Node *tail;
};
void *get_last (Node *xs) {
while (xs->tail != NULL) {
xs = xs->tail;
}
return xs->head;
}
typedef struct Node Node;
struct Node {
void *head;
Node *tail;
};
int main () {
int *p = (int *) malloc (sizeof(int));
*p = 2123456789;
Node *xs = (Node *) malloc (sizeof(Node));
xs->tail = NULL;
xs->head = 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 head;
Node tail;
}
static Integer getLast (Node xs) {
while (xs.tail != null) {
xs = xs.tail;
}
return xs.head;
}
static class Node {
Object head;
Node tail;
}
static Object getLast (Node xs) {
while (xs.tail != null) {
xs = xs.tail;
}
return xs.head;
}
ClassCastException
better than unsafe access
static class Node {
Object head;
Node tail;
}
public static void main (String[] args) {
Integer p = Integer.valueOf(2123456789);
Node xs = new Node();
xs.tail = null;
xs.head = 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 head;
Node<X> tail;
}
static <X> X getLast (Node<X> xs) {
while (xs.tail != null) {
xs = xs.tail;
}
return xs.head;
}
static class Node<X> {
X head;
Node<X> tail;
}
public static void main (String[] args) {
Integer p = Integer.valueOf(2123456789);
Node<Integer> xs = new Node<>();
xs.tail = null;
xs.head = 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>