C625 Project Covariant Return Types Group 5 members: Irene Cheng Nicholas Lamb Wesley Mackay...

26
C625 Project Covariant Return Types Group 5 members: Irene Cheng Nicholas Lamb Wesley Mackay December 4th, 2002
  • date post

    22-Dec-2015
  • Category

    Documents

  • view

    214
  • download

    0

Transcript of C625 Project Covariant Return Types Group 5 members: Irene Cheng Nicholas Lamb Wesley Mackay...

C625 Project

Covariant Return Types

Group 5 members:

Irene Cheng

Nicholas Lamb

Wesley Mackay

December 4th, 2002

Overview

• Motivation

• Project Objective

• Design & Implementation

• Test example

• Conclusions & Future Work

Motivation

• Return type of an overriding method must match return type of the top-level declaration

• This restriction simplifies the language but makes it inflexible

• Type information can be lost

• Casting can regain type information, but makes code less readable, slower and error-prone

Current Java Return Mechanism

Vector

Object elementAt(int)Object firstElement()Object lastElement()

PointVector

ObjectObjectObject

elementAt(int)firstElement()lastElement()

Invariant return type

Better Return Mechanism

Vector

Object elementAt(int)Object firstElement()Object lastElement()

PointVector

PointPointPoint

elementAt(int)firstElement()lastElement()

Covariant return type

Coding Example

• In current Java, we must use PointVector as follows:

Point origin(0,0);PointVector shapePts = new PointVector();

shapePts.addElement( new Point(1,1) );shapePts.addElement( new Point(2,-5) );shapePts.addElement( new Point(-3,0) );

// 2nd argument requires an explicit // cast, which is costly and confusing

distanceBetween(origin, (Point) shapePts.firstElement() );

Coding Example

• With covariant return types, we could use PointVector as follows:

Point origin(0,0);PointVector shapePts = new PointVector();

shapePts.addElement( new Point(1,1) );shapePts.addElement( new Point(2,-5) );shapePts.addElement( new Point(-3,0) );

// 2nd argument does not require casting,// making code simpler and safer

distanceBetween(origin, (Point) shapePts.firstElement() );

Project Objective

• Add support for covariant return types to improve flexibility and maintainability

• No changes to the JVM compiler

• No impact on current invariant return type mechanism (backwards compatibility)

Design & Implementation

• Phase 1

Add support for covariant return types to virtual methods defined in class hierarchies

• Phase 2

Apply concept of covariance to primitive return types

• Phase 3

Extend the above capabilities to interface methods

ClassD

public ClassA foo();

ClassE

public ClassB foo();

ClassF

public ??? foo();

Phase 1 - Type Checking Mechanism

ClassA

ClassB ClassC

What return types should be allowed?

ClassD

public ClassA foo();

ClassE

public ClassB foo();

ClassF

public ClassC foo();

Design option 1 – Check against top level

ClassA

ClassB ClassC

Covariant only against the top-level

declaration

ClassD

public ClassA foo();

ClassE

public ClassB foo();

ClassF

public ClassC foo();

Problem – Context Dependent

ClassA

ClassB ClassC

Covariant rules broken by the removal

of ClassD

ClassD

public ClassA foo();

ClassE

public ClassB foo();

ClassF

public ClassB foo();

Design option 2 – Check against next level

ClassA

ClassB ClassC

Covariant model always maintained at

all levels

ClassD

public ClassA foo();

ClassE

public ClassB foo();

ClassF

public ClassB foo();

Design option 2 – Check against next level

ClassA

ClassB ClassC

Covariant model preserved when ClassD

is removed

Phase 2 - Primitive Types Hierarchy

• Concept of covariant return types can be applied to Java primitives because of widening conversions

• Widening conversions offer a form of substitutability

• Consider that an integer value is also a floating point value

• We can safely return an int at any call site expecting a float without affecting program logic

Phase 2 - Primitive Types Hierarchy

double

float

long

int

short

byte

char

boolean

Handling Arrays

• Array return types require extra checking

• We verify that the array’s element type is covariant and that the dimensions match

• Suppose in the parent we have a method:

int[][] omega(int i, float f);

• Then in a subclass:

int[] omega(int i, float f);

double[][] omega(int i, float f);

short[][] omega(int i, float f);

Phase 3 - Covariant Returns for Interfaces

• The implementation of an interface method can have a return type that is covariant to what is declared in the interface

• Since a class can implement multiple interfaces, the return type of an interface method should be covariant to all interface methods with the same signature

Phase 3 - Example of interfaces

InterfaceA

public short foo() {…}

InterfaceB

public float foo() {…}

ClassC implements InterfaceA, InterfaceB

public ??? foo() {…}

• We could not define such a ClassC in conventional Java because it would be impossible to satisfy both interfaces

Phase 3 - Example of interfaces

InterfaceA

public short foo() {…}

InterfaceB

public float foo() {…}

ClassC implements InterfaceA, InterfaceB

public short foo() {…}

• With our extension, we could return a short or a byte because either of these is covariant to both short and float

Phase 3 - Example of interfaces

InterfaceA

public boolean foo() {…}

InterfaceB

public float foo() {…}

ClassC implements InterfaceA, InterfaceB

public ??? foo() {…}

• Implementing multiple interfaces can still fail if there’s no common covariant type

Test Example

ClassX

ClassY

interfaceI

interfaceJ

ClassA

ClassB ClassC

ClassD

ClassE

Test Example

class ClassX {

ClassA classTest(Object o) { ClassA obj = new ClassA(0); return obj; }}

interface interfaceI { public int alpha(int a, int b);}

interface interfaceJ { public ClassC theta(float e);}

Test Example

class ClassY extends ClassX implements interfaceI, interfaceJ { ClassD classTest(Object o) { ClassD obj = new ClassD(0); return obj; }

public double alpha(int a, int b) { return 0; }

public ClassB theta(float e) { return new ClassB(12); }

Sample Output - Invalid return types

JVM Warning Messages:

Warning: In method ClassA::alpha(II)DD is not an assignment subtype of I

Warning: In method ClassY::theta(F)LClassB;LClassB is not an assignment subtype of LClassC

Conclusions & Future Work

• Covariant return types increase language flexibility and reduces the need for casting

• Offers backwards compatibility

• The JVM’s treatment of ‘signature’ introduces problems when dispatching

• Need to remove the return type from the signature string whenever two signatures are compared

• Better to store the return type in a separate string, apart from the method arguments