Parametric Polymorphism in Java: an Efficient Implementation for Parametric Methods

Size: px
Start display at page:

Download "Parametric Polymorphism in Java: an Efficient Implementation for Parametric Methods"

Transcription

1 Parametric Polymorphism in Java: an Efficient Implementation for Parametric Methods Mirko Viroli DEIS - Universita degli Studi di Bologna via Rasi e Spinelli Cesena (FC), Italy mviroli@deis.unibo.it ABSTRACT The typical implementations for parametric polymorphism in object oriented programming languages are space consuming, in that new binary code is created as new instantiations of parametric types are used. Recently, it was proposed a translation for parameterized types into Java, called LM translation, which avoids this problem by collecting type descriptors for parametric types at load-time. Another useful feature related to parametric polymorphism is that of parametric methods, which is often a necessary tool to completely benefit from th expressiveness and the code reuse of parametric polymorphism. In this paper the LM translator is extended in order to deal with parametric methods too. While previous implementations lead to a relevant size overhead, the one here proposed defers most of the overhead at the classes load-time, with only little overhead at run-time. It turns out that the general impact of this implementation on the code execution is definitely lower than that of previous approaches. 1. INTRODUCTION Parametric polymorphism is a programming mechanism widely adopted, and whose usefulness has been at this point well understood. It allows to abstract a piece of code from one or more types, making it reusable in many different contexts. The most frequent example of use is the implementation of collection data types, whose behaviour and features are independent from the type of the elements of the collection. Typical implementations of parametric polymorphism are Ada generics [1], C++ templates [6], and ML polymorphic functions or data types [8, 5]. In its former versions, Java has not provided parametric polymorphism, mainly in order to keep the language as simple as possible. Genericity is partially supported through the super-type Object from which each class extends. In fact, dealing with a common bound for all the types makes it possible to strengthen the code reuse of inclusive poly- Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. SAC 2001 Las Vegas, Nevada USA Copyright 2001 ACM /01/02..$5.00 morphism (inheritance), as the practice of programming in Java has revealed. However, the lack of parametric polymorphism has been recognized to be a serious limitation of expressiveness [4], thus many proposals for the extension of Java have been studied. They can be mainly divided in two groups: the proposals for extension of the Java Virtual Machine (JVM) or of parts of it [2, 7, 12], and the translation approaches [11, 3, 10, 13]. In the former case compatibility with existing Virtual Machines is lost, although they generally lead to more efficient implementations. The translation approaches on the contrary, may introduce a significant overhead in both space and time, but do not affect in any way the Virtual Machine, then producing code executable on all the existing Java platforms. In this paper we focus on the latter kind of implementation, which has in fact received more interest. Two important issues that greatly influence the design of a translator are (i) the full integration of parametric types with the core typing and (ii) performance. At this time the proposal that seems to better address these issues is LM translator [13]. It uses the basic idea of carrying type information at run-time through objects representing types, in a framework which is a mixture of previous approaches. It relies on the erasure technique as GJ translator [11] does, it uses type information created by the translator in a similar way to NextGen translator [3], and finally it supports parametric type instantiations at load-time as suggested in [2]. Full type-integration is reached in that both parametric types and type variables can be used in each context where a type identifier is expected. Overhead is bound to acceptable values due to a novel translation technique in which most of the run-time management needed to support the typeintegration is deferred at the classes load-time. This highly decreases the impact of the translation with respect to more naive implementations (see for instance the depiction of RM translator in [13]). An important feature that LM translator does not deal with yet, is that of parametric methods. A lot of useful operations involve two values belonging to different parametric types, for instance appending two different parametric lists in order to create a more general one. In this case parametric methods allow for a simple, concise and direct implementation, while parametric classes alone do not provide for satisfactory solutions. In this paper we extend the LM translator so as to deal

2 with parametric methods too, by applying its basic idea of type-integration through the creation of type descriptors at load-time. The main problem with the implementation of parametric methods is to deal with dynamic dispatching, which is needed when a parametric method is overridden by a more specific class. This is addressed by attaching to the type descriptors generated by LM data structures called Virtual Parametric Method Tables, containing the instantiations of the parametric methods that the current application may use. This is done as usual only once at load-time, highly reducing the impact on the execution speed. The result is a significant improvement with respect to older implementations for Java and C++, which typically create a different method for each different instantiation of its generic version, leading to dynamically increasing classes. As in [13, 3, 11], we generally describe the translation (i) by isolating a source code with minimal size but comprehending all the features of interest, (ii) by giving the corresponding translation and finally (iii) by providing a detailed description of both the translation behaviour and the execution of the translated code. In particular we tried to choose the examples that better allow to provide a comprehensive yet simple treatment of the problem. The remainder of the paper is organized as follows. Section 2 introduces LM translation, trying to keep the description both short and self-containing (see [13] for more details on it). Section 3 describes parametric methods, their usefulness, and the drawbacks of their typical implementations. Section 4 shows the implementation of parametric methods in LM supposing not to deal with dynamic dispatching, while Section 5 describes how this issue can be addressed by exploiting Virtual Parametric Methods Tables. Section 6 shows the details of the final translation, together with some evaluation of performance. Section 7 concludes. 2. LM TRANSLATION The typical implementation for parametric polymorphism in object-oriented programming languages relies on the socalled macro-expansion technique, or at least on some optimized variant of it [6, 10, 3]. A different version of the binary code is created for each different instantiation of the corresponding generic source code. This is done for parametric classes, parametric methods and parametric functions as well. In order to avoid the high consumption of space involved, LM translator for Java [13] applies the idea of mapping parametric types to objects representing type descriptors. In this way each object carries all the information needed to support type-integration. The overhead impact is highly decreased thanks to a novel technique that defers the creation of all the type descriptors at the loading of some client class. A table of type descriptors allowing for fast access, typically a Hashtable, is maintained so as to prevent double creations of descriptors, thus keeping memory overhead small. Each object that is an instance of a parametric type will refer to the corresponding type descriptor, namely to an entry in the table of descriptors. A type descriptor keeps the following information: a unique, incremental identifier assigned at creation time; the core class representation java.lang.class of the current class; an array of type descriptors storing the instantiation for the type parameters; the type descriptor of the direct super-type of the current one, called the father descriptor; an array of type descriptors representing those parametric types, used within the class in type-dependent operations, whose instantiation depends on the actual binding of the current type parameters, and which we call friend types. The class of type descriptors is called $TD, and has the following structure: public class $TD { public int ID; public java.lang.class c; public $TD[] params; public $TD[] friends; public $TD father; public $TD(Class c, $TD[] p) { public boolean checknew() { public boolean isinstance(object o) { The constructor is used to create a partially-defined type descriptor, so that one can check if the type descriptor has already been registered in the type descriptor table, stored in the $TDManager class (type descriptors manager). This checking process is realized through the method checknew. In case its result is true, the descriptor has then to be inserted in the descriptor table, namely it has to be registered, and then it has to be completed by filling the fields friends and father. The class $TDManager has the following signature: public class $TDManager { private static Hashtable h; public static int countid; static{ //Initialization code for h public static $TD register(class c) { public static $TD register(class c,$td[] p) { Two methods for registering type descriptors are provided; they respectively register non-parametric and parametric types 1. Both may return an already-registered type descriptor or create and return a new one. See Figure 1 for the actual implementation of both $TD and $TDManager, along with that of interface $Parametric, which each parametric class will implement, and with the depiction of class $Array, which is used to integrate arrays and parametric types 2. Now consider the example code of Figure 2. Class Cell<T> is a simple wrapper for an element of type T, and provides a getter method (get), a setter method (set), a setter method that assigns the field only if the object conforms to the type T (setifpossible) and finally a method that returns a Cell<String> representation of the receiver object (getcstring). Notice that method setifpossible realizes a type-dependent operation, which requires run-time type 1 Notice that since a non-parametric type may be the instantiation for a type parameter, and these instantiations are represented through type descriptors, we also need type descriptors for non-parametric types 2 We won t discuss about arrays in this paper, since their influence on parametric methods does not issue new problems than those discussed in [13].

3 public class $TD { public int ID; //Unique identifier public Class c; public $TD[] params,friends; public $TD father; private int hashvalue; private boolean bnew=true; public static $TD[] voidtds=new $TD[0]; public static $TD objtd; static { objtd=new $TD(Object.class,voidTDs); objtd.id=0; objtd.father=objtd; public $TD(Class c, $TD[] p) { this.c=c; params=p; ID=-1; processhash(); public boolean checknew() { if (!bnew) return bnew; bnew=false; return true; private void processhash() { // Implementation for a hash function public int hashcode() { return hashvalue; public boolean equals(object obj) { // Simple equality test // Implementing subtyping public boolean isinstance(object o) { if (o instanceof $Parametric){ int Q;$TD T=(($Parametric)o).getTD(); for (;(Q=T.ID)!=ID && Q!=0;T=T.father); return Q==ID; else return c.isinstance(o); public class $TDManager { private static Hashtable h=new Hashtable(101,0.75f); public static int countid=1; static{ h.put($td.objtd,$td.objtd); public static $TD register(class c) { $TD T=new $TD(c,$TD.voidTDs); Object o=h.get(t); if (o==null){ h.put(t,t); T.ID=countID++; T.father=register(c.getSuperclass()); return T; return(($td)o); public static $TD register(class c,$td[] p) { $TD T=new $TD(c,p); Object o=h.get(t) ; if (o==null){ h.put(t,t); T.ID=countID++; return T; return(($td)o); public class $Array implements $Parametric { private $TD $td; public Object[] ao; public $Array($TD $td,int n){ this.$td=$td; ao=new Object[n]; public $Array($TD $td,object[] a){ this.$td=$td; ao=a; public $TD gettd() { return $td; public static $TD createtd($td[] params) { // Simple facility to create descriptors for Arrays public interface $Parametric { public $TD gettd(); Figure 1: Implementation for library classes of standard LM translation class Cell<T>{ private T t; Cell(T t){ this.t=t; void set(t t){ this.t=t; T get(){ return t; void setifpossible(object o){ if (o instanceof T) this.t=(t)o; Cell<String> getcstring(){ return new Cell<String>(""+t); class Pair<R,S> extends Cell<R>{ private S s; Pair(R r,s s){ super(r); this.s=s; void setsecond(s s){ this.s=s; S getsecond(){ return s; Pair<S,R> getreverse(){ return new Pair<S,R>(s,get()); class Client{ public static void main(string[] s){ Cell<Integer> c1=new Cell<Integer>(null); c1.set(new Integer(1)); Integer I=c1.get(); c1.setifpossible("2"); // "2" is not stored into c1 Cell<String> c2=c1.getcstring(); // new Cell<String>("1") Pair<Integer,String> p=new Pair<Integer,String>(I,c2.get()); // pair[1,"1"] Object o=p.getreverse(); c1=(o instanceof Cell<Integer>)?(Cell<Integer>)o:null; // c1=null Figure 2: An example of source code

4 information about the actual instantiation of the type variable T. Class Pair<R,S> extends Cell and defines a getter and a setter method for the second element of the pair, together with a getreverse method returning a new pair where the two elements are inverted. Within Pair<R,S>, the type Pair<S,R> is one of those types whose type parameters depend on the current binding of the type variables R and S, that is a friend type of Pair<R,S>. Hence in general, the type descriptor for Pair<X,Y> will contain in the field friends the type descriptor for Pair<Y,X>. Class Client uses some instantiation of the parametric classes Cell and Pair for type-dependent operations, such as the creation of class instances, instanceof tests and casts (i.e. type-conversion operations). Notice that our management has the only goal of allowing each parametric object to refer its corresponding type descriptor built at load-time, so as to support type-dependent operations in a fast way. The translation for the source code is given in Figure 3. The translation of generic classes Cell and Pair relies on the erasure technique [11]. This mainly means that all the occurrences of the type parameters in which they are not used for type-dependent operations are simply translated to Object 3. For instance, a class Vector<T> is translated into a Vector class storing Object elements. Static controls and insertions of casts are used to support this kind of mapping (see the body of Client.Main in Figure 3). The translation technique is however unable to properly translate the occurrences of type variables used in typedependent operations [11]. LM translator differs from the standard erasure technique in that it translates this kind of occurrences into operations exploiting type descriptors. Within Cell and Pair the argument list of each constructor is augmented with a $TD argument containing the type descriptor for the current instantiation. This descriptor will be put into a newly-created instance field called $td, which can be accessed through the method gettd inherited from the interface $Parametric. Each parametric class provides then a static method called createtd, which can be used to register a type descriptor of the receiving class. This method checks for an alreadyregistered descriptor to exist, in this case this descriptor is simply returned. In the opposite case instead, a new descriptor is created and registered, and the fields father and friends are filled, possibly by recursively calling the method createtd of other generic classes. The type descriptor of a parametric type is used to implement type-dependent operations. For instance, its field param is used for the instance test exploited in the method Cell.setIfPossible, or to create the reversed pair in the method Pair.getReverse. When translating a client class, i.e. a class which uses instantiations of some parametric type, the translator should gather all these instantiations, and insert the code to register the corresponding type descriptors in the static initiliazer of this client. So, each client actually creates the type descriptors it will need immediately after its loading. This is clearly the case of class Client, which directly uses Cell<Integer> and Pair<Integer,String>, but also 3 More generally, dealing with bounded and f-bounded polymorphism, erasure technique translates a type-variable to its bound, which is Object by default. See [10] for more details. of class Cell, which uses Cell<String>. The registration of a generic type descriptor is realized through the corresponding createtd method, while that of a non-generic types by directly using the method $TDManager.register. These type descriptors are passed to the parametric objects when they are created, and will be used for implementing type-dependent operations over parametric types, namely instanceof tests and casts. This kind of operation is realized exploiting the method $TD.isInstance, shown in Figure 1. If the object o is not an instance of a parametric type the core reflective functionality Class.isInstance is used. In the opposite case the interface $Parametric is used to access the type descriptor of o. Then, through a navigation via the field $TD.father the subtyping relation is checked. 3. PARAMETRIC METHODS Parametric classes allow a programmer to define generic abstract data types independently from the value of other types, which are mapped to type parameters of the generic class. Any instance method of a parametric class is used to define an operation on the value represented by the receiver object, or at most an operation between two data values belonging to the same parametric type. Most times however, one may need to define an operation that does not involve two data values belonging to the same instantiation of the same generic class. With parametric classes only, the problem can be solved by defining a wrapper parametric class having both the type variables of the two generic classes involved in the operation. Considering the class Pair<R,S>, suppose one wants to define an operation that takes two elements Pair<A,B> and Pair<C,D> and returns the pair Pair<A,C>. A possible implementation is the following: class TwoPairs<A,B,C,D>{ Pair<A,B> p1; Pair<C,D> p2; TwoPairs(Pair<A,B> p1,pair<c,d> p2){ this.p1=p1;this.p2=p2; Pair<A,C> compose(){ return new Pair<A,C>(p1.get(),p2.get()); Pair<String,String> p1= Pair<Double,Double> p2= Object o=new TwoPairs<String,String, Double,Double>(p1,p2).compose(); This implementation is not satisfactory. First of all, it requires a new class to be defined for each operation over two different parametric classes. Moreover, it needs a new object to be created, storing the two elements involved in the operation. In principle, the latter drawback can be avoided by defining the operation as a static method and passing to it the two elements. Consider however that the semantics of static methods of parametric classes is not already standardized [12], so the right semantics for this case, which is that of heterogeneous-based implementations [3], may not be available. Parametric methods may help in coding the functionality in a more elegant way, as follows: class Pair<R,S>{ <C,D> Pair<R,C> compose(pair<c,d> p2){ return new Pair<R,C>(get(),p2.get());

5 public class Cell implements $Parametric { static $TD $cl; static{ $cl=createtd(new $TD[]{ $TDManager.register(String.class)); public static $TD createtd($td[] params) { $TD t=$tdmanager.register(cell.class,params); if (t.checknew()){ t.father=$td.objtd; t.friends=$td.voidtds; return t; public $TD gettd() { return $td; private $TD $td; private Object t; Cell($TD $td,object t){ this.$td=$td; this.t=t; void set(object t){ this.t=t; Object get(){ return t; void setifpossible(object o){ if ($td.params[0].isinstance(o)) t=o; Cell getcstring(){ return new Cell($cl,""+t); public class Pair extends Cell { public static $TD createtd($td[] params) { $TD t=$tdmanager.register(pair.class,params); if (t.checknew()){ t.father=cell.createtd(new $TD[]{params[0]); t.friends=new $TD[1]; t.friends[0]=pair.createtd( new $TD[]{params[1],params[0]); return t; public $TD gettd() {return $td; private $TD $td; Object s; public Pair($TD $td,object r,object s) { super($td.father,r); this.$td=$td; this.s=s; public void setsecond(object s) { this.s=s; public Object getsecond() { return s; public Pair getreverse() { return new Pair($td.friends[0],s,get()); public class Client { static $TD[] $t=new $TD[4]; static{ $t[0]=$tdmanager.register(integer.class); //Integer $t[1]=cell.createtd(new $TD[]{$t[0]); //Cell<Integer> $t[2]=$tdmanager.register(string.class); //String $t[3]=pair.createtd(new $TD[]{$t[0],$t[2]);//Pair<Integer,String> public static void main(java.lang.string[] args) { Cell c1=new Cell($t[1],null); // new Cell<Integer>(null); c1.set(new Integer(1)); Integer I=(Integer)c1.get(); c1.setifpossible("2"); Cell c2=c1.getcstring(); Pair p=new Pair($t[3],I,c2.get()); //new Pair<Integer,String>(I,c2,get()); Object o=p.getreverse(); c1=$t[1].isinstance(o)?(cell)o:null; // o instanceof Cell<Integer>? Figure 3: Translation of the source code Pair<String,String> p1= Pair<Double,Double> p2= Object o=p1.compose<double,double>(p2); Some examples of operation that may benefit from this kind of management are: appending two parametric lists, mapping a function to all the elements of a list, performing the cartesian product of two sets, and so on. The most straightforward implementation for parametric methods follows the idea of the implementations for parametric types based on macro-expansion. In particular, a new method is created for each different instantiation. Considering the code above, a compiler would create the following code: class Pair$String_String${ \\ each occurrence of type variables R and S \\ are substituted to String and String, then.. Pair$String_Double$ compose$double_double$ (Pair$Double_Double$ p2){ return new Pair$String_Double$(get(),p2.get()); Pair$String_String$ p1= Pair$Double_Double$ p2= Object o=p1.compose$double_double$(p2); This implementation is space-consuming: the binary code of the program increases as different instantiations of the method are used. Even though some optimized solution (see for instance [3]) reduces the binary code created, the drawbacks remain: there is not limit in principle on the size of a class due to this kind of management. The problem is even more dramatic for the Java architecture in particular, which may rely on remote class loading. Here, the size of the class files is preferred to be fixed and as small as possible. In [9] it is sketched a translation for parametric methods into Java in which the Class object of each instantiation of a type variable is passed as argument. This proposal however has a number of problems, as the authors themselves pointed out: it does not address any performance issue, it does not allow for nesting parameter-

6 izations (as in Cell<Cell<T>>), and it does not integrate well with parametric classes and the core typing. Obviously, as mentioned in the introduction, the problem holds if one needs the full type-integration of parametric types in the core typing. In the opposite case in fact there is no need of carrying type information about the actual instantiation, and the erasure technique still remains a sufficient tool (see [11]). The importance of this integration has however been recognized in several papers [3, 13, 12]. 4. PARAMETRIC METHODS WITHOUT DYNAMIC DISPATCHING Suppose not to deal with dynamic dispatching, i.e. having only parametric methods declared private, static or final, or anyway when they are not overridden by a more specific version into a sub-class. Then, the related implementation in the framework of LM translation can be built as follows. The basic idea is to manage method descriptors as well as type descriptors. They will be passed as the first argument of the parametric method, and they will contain all the information needed to deal with type-operations. While a type descriptor is identified by a Class object and an array of type descriptors representing type variables, a method descriptor will be identified by (i) the type descriptor of the parametric class within it is defined, (ii) an identifier of the method within the class and finally (iii) an array of type parameters representing the instantiations of the method type variables. So, for instance, we identify the method m with type parameter T, invoked to an instance of the parametric class C<R,S>, with the notation C<R,S>.m<T>. Unlikely type descriptors, method descriptors have not to provide for subtyping, hence they do not have a super-descriptor field and they do not provide any unique identifier. In Section 2 we showed that a type descriptor, say t, may refer a set of type descriptors, that we call its friend types, whose binding of type parameters depend on the binding of the type variables of t. They were stored into the field t.friends. When dealing with parametric methods, this management is a little more complicate, as now the idea of binding dependency has to be extended. In particular, both parametric methods and parametric types will have friend types as well as friend methods. See the source code of Figure 4. Given two instantiations for R and S respectively, namely X and Y, the type descriptor for Pair<X,Y> has the friend type Pair<Y,X>. Moreover, due to the body of the method movefirst, the type Pair<X,Y> has also the friend method Pair<X,Y>.chgSecond<Y> whose type variable instantiation depends on the current binding of the type variables of Pair. Analogously, given an instantiation Z for the type variable T, the method descriptor Pair<X,Y>.chgSecond<Z> has the friend type Pair<X,Z>, while Pair<X,Y>.chgFirst<Z> has the friend method Pair<Y,X>.chgSecond<Z>, since Z influences their actual instantiation. So, the signature of the class of method descriptors, called $MD, is the following: public class $MD { public int mid; // method identifier public $TD td; // type descriptor public $TD[] params; // method s type variables public $TD[] friendtd; // friend types public $MD[] friendmd; // friend methods public $MD($TD t, int mid, $TD[] p) { public boolean checknew() { The class $TD has just to be changed by adding a field for friend methods, called friendmd, and renaming the field friends to friendtd. The class $MDManager, analogously to $TDManager, keeps track of all the method descriptors and provides a registration functionality that prevents double registrations. Its signature is: public class $MDManager { private static Hashtable h; static{ //Initialization code public static $MD register ($TD t,int mid,$td[] params){ For brevity, we omit the actual implementation for both $MD and $MDManager. It is straightforward and moreover in Section 6 we will provide the final one, which is quite similar but deals with dynamic dispatching too. In Figure 4 the translation for this source code is also reported. When a class provides some parametric method, whether it is parametric or not, the translator inserts a createmd static method which handles the creation of method descriptors analogously to what method createtd does for type descriptors. 4 A client class now in its static initializer has to create and register the method descriptors as well as type descriptors, and has to pass method descriptors when invoking parametric methods. When not dealing with dynamic dispatching it is possible to statically infer the instantiations of the parametric classes on which each parametric method is invoked. Thus, it is possible to prepare the static initializer of a client class in an appropriate way. 5. DYNAMIC DISPATCHING Consider the following code: class ExPair<R,S> extends Pair<R,S>{ ExPair(R r,s s){super(r,s); <T> Pair<R,T> chgsecond(t t){ return new ExPair<R,T>(r,t); class Client{ boolean dynamictest(pair<integer,string> p){ Object o=p.chgsecond<double>(new Double(2)); return o instanceof ExPair<Integer,Double>; The two method descriptors corresponding to the signatures ExPair<Integer,String>.chgSecond<Double> and Pair<Integer,String>.chgSecond<Double> contain different information. For instance, the former has the friend type ExPair<Integer,Double> while the second has the friend type Pair<Integer,Double>. These friend types are used to create instances of Pair and ExPair respectively. In particular, passing to the method dynamictest an argument of type ExPair<Integer,String> would cause the method to return a true value, while if the argument type is 4 In case of a non-generic class defining method descriptors, the translation accommodates it so that its type descriptor is automatically registered at load-time, and can be accessed in order to properly register the method descriptors.

7 class Pair<R,S> extends Cell<R>{ //Source S s; Pair(R r,s s){super(r); this.s=s; Pair<S,R> swap(){return new Pair<S,R>(s,get()); <T> Pair<T,S> chgfirst(t t){ return swap().chgsecond<t>(t).swap(); <T> Pair<R,T> chgsecond{t t{ return new Pair<R,T>(get(),t); Pair<R,R> movefirst(){return chgsecond<r>(get()); class Pair{ //Translation Object s; Pair(Object r,object s){super(r); this.s=s; Pair swap(){return new Pair($td.friendTD[0],s,get()); Pair chgsecond{$md $m,object t{ return new Pair($m.friendTD[0],get(),t); Pair chgfirst($md $m,object t){ return swap().chgsecond($m.friendmd[0],t).swap(); Pair movefirst(){ return chgsecond($td.friendtd[0],get()); $TD $td; public $TD gettd(){ return $td; static $TD createtd($td[] params){ static $MD createmd($td t,int ID,$TD[] params){ class Client{ //Source public boolean simpletest(){ Pair<Integer,String> p= new Pair<Integer,String>(new Integer(1),"2"); Pair<Double,String> p2= p.changefirst<double>(new Double(1)); return (p2.reverse() instanceof Pair<String,Double>); class Client{ //Translation public boolean simpletest(){ Pair p=new Pair(t[3],new Integer(1),"2"); Pair p2=p.changefirst(m[0],new Double(1)); return t[4].instanceof(p2.getreverse()); $TD[] t=new $TD[5]; $MD[] m=new $MD[1]; static{ t[0]=$tdmanager.register(integer.class); t[1]=$tdmanager.register(string.class); t[2]=$tdmanager.register(double.class); t[3]=pair.createtd(new $TD[]{t[0],t[1]); t[4]=pair.createtd(new $TD[]{t[1],t[2]); m[0]=pair.createmd(t[3],0,new $TD[]{t[2]); Figure 4: An example of code and translation with parametric methods when not dealing with dynamic dispatching Pair<Integer,String> the result is false. This highlights that in the two cases different method bodies for chgsecond are actually executed, thus different method descriptors are needed. So, what kind of method descriptor should we pass at the invocation of chgsecond? This example shows that when dealing with dynamic dispatching it is not possible in general to statically know which method descriptor has to be passed and used by the method body. What we need is a technique allowing to dynamically select the appropriate method descriptor depending on the actual type descriptor of the receiver object. Doing so, we also require run-time overhead to be as small as possible 5. To avoid this problem, we use a technique roughly similar to a standard Virtual Method Table, used to deal with dynamic dispatching of non-parametric methods. If a class defines a parametric method that is not declared static, private or final, then the corresponding type descriptor will keep a table of parametric method descriptors for that method, a VPMT for short (Virtual Parametric Method Table). Instead of passing to a parametric method a method descriptor, the client passes the position of the descriptor within the corresponding VPMT, so that any access can be resolved dynamically in a fast way. Considering the example shown above, with this kind of management the descriptors for Pair<Integer,String> and ExPair<Integer,String> will have both two vector structures: one representing the VPMT for the method chgfirst and one for the method chgsecond. When a client registers the method chgsecond<double> a new entry is inserted in both the VPMTs for chgsecond, at the same position. In particular, the method descriptor Pair<Integer,String>.chgSecond<Double> is inserted in 5 In a trivial solution we would create the method descriptor by-need, but the corresponding overhead would be unacceptable. the VPMT of Pair<Integer,String>, while the method descriptor ExPair<Integer,String>.chgSecond<Double> into that of ExPair<Integer,String>. The result of the registration is the index in the VPMTs, which is the same in both the types Pair<Integer,String> and ExPair<Integer,String>. This index is passed at the method invocation-time, and is used to access the VPMT in the type descriptor of the receiver object. 6. IMPLEMENTATION DETAILS The final translation of class Pair and ExPair is reported in Figure 5, together with the translation for the following simple client class: class Client{ void main(){ Pair<Integer,String> p= new Pair<Integer,String>(new Integer(1),"2"); Pair<Double,String> p2= p.chgfirst<double>(new Double(1)); ExPair<Integer,String> e2= new ExPair<Integer,String>(new Integer(1),"2"); Object o=e2.chgfirst<string>(""); Object o2=e2.chgsecond<double>(new Double(1)); The implementation of library classes $MDManager and $MD is reported in Figure 6, along with the new signature for class $TD, which includes an array of Vector objects (representing VPMTs for each parametric method), and which uses for the field friendmd an array of int values (positions in the VPMTs) instead of one of $MD values. The implementation for $TDManager remains unchanged. From the Client point view, the translation is changed only in the information returned when registering a method descriptor. This is no more the descriptor itself, but just an int value representing its position within the method s VPMT. Then, the first argument of the method register

8 class Pair extends Cell{ Object s; Pair($TD $td,object r,object s){ super($td.father,r); this.$td=$td;this.s=s; Pair swap(){return new Pair($td.friendTD[0],s,get()); Pair chgsecond(int $p,object t){ return new Pair((($MD)$td.$MDs[1].elementAt($p)).friendTD[0],get(),t); Pair chgfirst(int $p,object t){ return swap().chgsecond((($md)$td.$mds[0]. elementat($p)).friendmd[0],t).swap(); Pair movefirst(){return chgsecond($td.friendmd[0],get()); private $TD $td; public $TD gettd(){ return $td; static public $TD createtd($td[] params){ $TD t=$tdmanager.register(pair.class,params); if (t.checknew()){ t.$mds=new Vector[]{new Vector(),new Vector(); t.father=cell.createtd(new $TD[]{params[0]); t.friendtd=new $TD[]{Pair.createTD( new $TD[]{params[1],params[0]); t.friendmd=new int[]{pair.createmd( t,new Integer(1),new $TD[]{params[0]); return t; static public int createmd($td t,integer mid,$td[] params){ int ID=mID.intValue(); $MD m=$mdmanager.register(t,id,params); if (m.checknew()){ t.$mds[id].addelement(m); m.lpos=t.$mds[id].size()-1; if (ID==0){ //chgfirst m.friendmd=new int[]{createmd(t.friendtd[0], new Integer(1),new $TD[]{params[0]); else if (ID==1){ //chgsecond m.friendtd=new $TD[]{createTD( new $TD[]{t.params[0],params[0]); $MDManager.propagate(m); return m.lpos; class ExPair extends Pair{ ExPair($TD $td,object r,object s){ super($td.father,r,s);this.$td=$td; Pair chgsecond(int $p,object t){ return new ExPair((($MD)$td.$MDs[1].elementAt($p)).friendTD[0],get(),t); $TD $td; public $TD gettd(){ return $td; static public $TD createtd($td[] params){ $TD t=$tdmanager.register(expair.class,params); if (t.checknew()){ t.father=pair.createtd(params); t.$mds=new Vector[]{new Vector(),new Vector(); for (int i=0;i<2;i++) { Enumeration e=t.father.$mds[i].elements(); for (;e.hasmoreelements();){ $MD m=($md)e.nextelement(); createmd(t,new Integer(m.mID),m.params); return t; static public int createmd( $TD t,integer mid,$td[] params){ int ID=mID.intValue(); $MD m=$mdmanager.register(t,id,params); if (m.checknew()){ t.$mds[id].addelement(m); m.lpos=t.$mds[id].size()-1; if (ID==0){ // chgfirst m.friendtd=(($md)t.father.$mds[0]. elementat(m.lpos)).friendtd; m.friendmd=(($md)t.father.$mds[0]. elementat(m.lpos)).friendmd; else if (ID==1){ //chgsecond m.friendtd=new $TD[]{createTD(new $TD[]{ t.params[0],params[0]); $MDManager.propagate(m); return m.lpos; class Client{ public void main(string[] s){ Pair p=new Pair(t[3],new Integer(1),"2"); Pair p2=p.chgfirst(m[0],new Double(1)); ExPair e2=new ExPair(t[4],new Integer(1),"2"); Object o=e2.chgfirst(m[1],new Double(1)); Object o2=e2.chgsecond(m[2],new Double(1)); static $TD[] t=new $TD[5]; static int[] m=new int[3]; static { t[0]=$tdmanager.register(integer.class); t[1]=$tdmanager.register(string.class); t[2]=$tdmanager.register(double.class); t[3]=pair.createtd(new $TD[]{t[0],t[1]); m[0]=pair.createmd(t[3],new Integer(0),new $TD[]{t[2]); t[4]=expair.createtd(new $TD[]{t[0],t[1]); m[1]=pair.createmd(t[3],new Integer(0),new $TD[]{t[1]); m[2]=pair.createmd(t[3],new Integer(1),new $TD[]{t[1]); Figure 5: Translation for classes Pair, ExPair and Client

9 public class $MD { public int mid; public int lpos=-1; public $TD td; public $TD[] params; public $TD[] friendtd; public int[] friendmd; private int hashvalue; private boolean bnew=true; public static $MD[] voidmds=new $MD[0]; public $MD($TD t, int mid, $TD[] p) { this.td=t; this.mid=mid; params=p; processhash(); public boolean checknew() { if (!bnew) return bnew; bnew=false; return true; public boolean equals(object obj) { //Simple equality test public int hashcode() { return hashvalue; void processhash() { //Implementation for a hash function public class $MDManager { private static Hashtable h=new Hashtable(); private static Class[] cc=new Class[]{ $TD.class,Integer.class,$TD.voidTDs.getClass(); public static $MD register($td t,int mid,$td[] params) { $MD S=new $MD(t,mID,params); Object o=h.get(s); if (o==null){ h.put(s,s);return S; return(($md)o); public static void propagate($md m){ try{ for (Enumeration e=$tdmanager.h.keys();e.hasmoreelements();){ $TD t=($td)e.nextelement(); if (t.father.id==m.td.id){ Method mt=t.c.getmethod("createmd",cc); mt.invoke(t.c,new Object[]{t,new Integer(m.mID),m.params); catch (Exception e){ //Never actually thrown public class $TD { public int ID; public Class c; public $TD[] params; public $TD father; public $TD[] friendtd; public int[] friendmd; public Vector $MDs[]; Figure 6: Implementation of library classes when dealing with parametric methods and dynamic dispatching in class $MDManager should not in general be the receiver object s type descriptor t. Instead, it has to be the greatest (in the sense of the subtype relation) type descriptor which defines the method and which represents a super-type for the type of t. This because as we will see later, the registration of a method causes a down-propagation of registrations to all the sub-descriptors of the receiver one. This is why we require to start from the greatest one. Each type descriptor keeps an array of Vector elements called $MDs containing method descriptors. Each vector represents the VPMT for one of the parametric methods which is defined by the current class, or inherited from the superclass. So, in the body of a parametric method, the first argument, representing a position in a VPMT, is used for accessing the proper method descriptor in the VPMT of the current type descriptor this.$td (see for instance the body of Pair.chgSecond). The main concern with the management of VPMTs is that independently from the order of registrations for type descriptors and method descriptors, the VPMT for a given method should contain analogous data in each type descriptor which may use that method. In particular, all these related-vpmts must contain the same number of elements, and at a given position they must contain the method descriptor for the same instantiation of the parametric method; what changes is only the field $MD.td. Suppose for instance, that the type descriptor Pair<X,Y> has in the first VPMT (that of method chgfirst) the method descriptors Pair<X,Y>.chgFirst<A>, Pair<X,Y>.chgFirst<B> and Pair<X,Y>.chgFirst<C>, orderly. Then, each type descriptor for a subtype of Pair<X,Y> that may use chgfirst, and that has been already registered in $MDManager, say it is ExPair<X,Y>, has to contain an analogous VPMT, having ExPair<X,Y>.chgFirst<A>, ExPair<X,Y>.chgFirst<B> and ExPair<X,Y>.chgFirst<C>. This is necessary if we want to guarantee that the dynamic resolution of a method descriptor would never fail to return the proper one. In order to realize this, we modified both the registration of type descriptors and that of method descriptors in the following way. The registration for a new type descriptor should check in the VPMT of its father which method descriptors it already contains, and consequently create its own versions. Suppose Pair<X,Y> contains the three method descriptors above, and one registers ExPair<X,Y> for the first time. Then, by looking at the VPMT of Pair<X,Y> the translated code has to cause the creation of the three method descriptors for ExPair<X,Y>. Analogously, the registration for a new method descriptor has to propagate a corresponding registration in each type descriptor representing a sub-type of the current one. This is why we need a registration starting from the greatest type possible. For instance, the method m[2] is registered by passing the descriptor for Pair<Integer,String> even though it is invoked over an element whose static type is ExPair<Integer,String>. The propagation code is stored in the method propagate of class $MDManager 6. It accepts a method descriptor m already registered, it looks for type descriptors which have m.td as father types, and calls the method createmd for all of them. This recursively causes all the VPMT to be adjusted to the new registration. Supposing the situation above in which both Pair<X,Y> and ExPair<X,Y> have three method descriptors, if one registers Pair<X,Y>.chgFirst<D> then the descriptor for ExPair<X,Y>.chgFirst<D> is created too, and both are inserted in the fourth position. The translation of the method createtd in each parametric class is changed in that the VPMT structures are initialized and then filled on the basis of the content of the VPMT of the father descriptor (see method ExPair.createTD), as explained above. Analogously, the method createmd is changed in that in its body the invocation for the propagation method is inserted. Moreover, the first time a method descriptor is registered it is added to the corresponding VPMT and its current 6 It makes use of reflection features, that s way we had to use the class Integer for its second argument

10 position is stored in the field $MD.lPos. Then, depending on the method identifier mid, the fields friendtd and friendmd are filled by registering friend type descriptors and friend method descriptors. 6.1 On Performance Performance is a very important issue when developing a translation. In fact, it is also the reason why we are proposing a new translation, which we claim to have a minor general impact on performance with respect to that of NextGen [3], which translates a very similar language 7. Here we motivate why the translation for parametric methods proposed here has minor performance impact than that of NextGen, which is in fact the only translator dealing with this feature. We can do this by directly extending the considerations reported in [13]. Considering the class file overhead, that is the increasing of the bytecode size, NextGen remains more inefficient, since as new instantiations of parametric methods are used, new methods are added to the class. On the contrary, LM increases classes independently from the number of instantiations actually used, typically from 1kbyte to 2kbytes of code is added to both client classes and classes defining parametric methods. The run-time overhead of LM is instead a little higher than that of NextGen, but is anyway small. In fact, the only new overhead introduced by the translation we are discussing here occurs when invoking a method, in particular we have an array access indirection, for accessing the proper VPMT, and a vector access indirection, for accessing the descriptor in the VPMT. Without considering parametric methods, the load-time overhead of NextGen is a couple of degree of magnitude greater than that of LM. This is because while LM just executes some more bytecode after the loading of a class, NextGen loads new classes, involving slow operating system operations. The management of parametric methods is quite similar to that of parametric classes, so in typical cases its impact on load-time performance is analogous. Considering degenerative cases, where a lot of instantiations of parametric types are used, and inheritance hierarchy has a considerable depth, the impact on load-time may increase at most by one degree of magnitude. Even in these cases, the overhead would remain one degree of magnitude lesser than that of NextGen. Furthermore, as already pointed out, in these generative cases the class files are considerably increased by NextGen, possibly with dramatic impact in case of remote loading. 7. CONCLUSIONS One of the most succeeding translation of parametric types into Java is given by LM translator. It allows for full type integration, and it highly decreases the size overhead (typical of NextGen), at the cost of a little run-time overhead. However, it lacks parametric methods management, which is an unavoidable feature if one wants to completely exploit the code reuse and the expressiveness of generic programming. In this paper we extend the behaviour of LM translator so as to deal with parametric methods. To do so, we 7 The only differences are due to minor issues like static attributes and inner classes make use of a novel technique exploiting Virtual Parametric Method Tables, which allows to resolve dynamic dispatching in a very fast way. The framework of LM translator makes it possible to defer the creation of type descriptors and method descriptors at load time, thus guaranteeing a little affection on performance even though the management required seems considerable. The next logical step in this work is to abstract and then formalize the compilation of parametric methods, so as to highlight how our technique could be used not only for a translation into Java, but as a general technique for compilers for languages with parametric polymorphism. 8. REFERENCES [1] Ada. Reference manual for the Ada programming language. GPO , [2] O. Agesen, S. Freund, and J. C. Mitchell. Adding parametrized types to Java. In Conference on Object-Oriented Programming, Systems, Languages and Applications, pages ACM, October [3] C. Cartwright and G. Steele. Compatible genericity with run-time types for the Java programming language. In Conference on Object-Oriented Programming, Systems, Languages and Applications, pages ACM, October [4] J. Guy L. Steel. Growing a language. Journal of Higher-Order and Symbolic Computation (Kluwer), 12,3: , [5] J.D.Ullman. Elements of ML programming. Prentice Hall, [6] M.Ellis and B.Stroustroup. The Annotated C++. Addison-Wesley, [7] A. C. Meyers, J. A. Bank, and B. Liskov. Parameterized types for Java. In Symposium on Principles of Programming Languages, pages ACM, [8] R. Milner. The Standard ML core language. In Symposium on Lisp and Functional Programmin. ACM, [9] M. Odersky, E. Runne, and P. Wadler. Two ways to bake your Pizza - Translating parameterized types into Java. Technical Report CIS , University of South Australia, [10] M. Odersky and P. Wadler. Pizza into Java: Translating theory into practice. In Symposium on Principles of Programming Languages, pages ACM, [11] M. Odersky, P. Wadler, G. Bracha, and D. Stoutamire. Making the future safe for the past: Adding Genericity to the Java programming language. In Conference on Object-Oriented Programming, Systems, Languages and Applications, pages ACM, October [12] J. H. Solorzano and S. Alagic. Parametric polymorphism for Java: A reflective solution. In Conference on Object-Oriented Programming, Systems, Languages and Applications, pages ACM, [13] M. Viroli and A. Natali. Parametric Polymorphism in Java: an approach to translation based on reflective features. In Conference on Object-Oriented Programming, Systems, Languages and Applications, pages ACM, Oct 2000.

A Type-Passing Approach for the Implementation of Parametric Methods in Java

A Type-Passing Approach for the Implementation of Parametric Methods in Java A Type-Passing Approach for the Implementation of Parametric Methods in Java MIRKO VIROLI c British Computer Society 2003 DEIS, Università di Bologna, via Rasi e Spinelli 176, 47023 Cesena (FC), Italy

More information

Safe Instantiation in Generic Java

Safe Instantiation in Generic Java Safe Instantiation in Generic Java January 31, 2003 Abstract This paper presents the safe-instantiation principle a new design principle for evaluating extensions of Java with support for generic types.

More information

Late-bound Pragmatical Class Methods

Late-bound Pragmatical Class Methods Late-bound Pragmatical Class Methods AXEL SCHMOLITZKY, MARK EVERED, J. LESLIE KEEDY, GISELA MENGER Department of Computer Structures University of Ulm 89069 Ulm, Germany {axel, markev, keedy, gisela@informatik.uni-ulm.de

More information

More About Objects. Zheng-Liang Lu Java Programming 255 / 282

More About Objects. Zheng-Liang Lu Java Programming 255 / 282 More About Objects Inheritance: passing down states and behaviors from the parents to their children. Interfaces: requiring objects for the demanding methods which are exposed to the outside world. Polymorphism

More information

Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

Weiss Chapter 1 terminology (parenthesized numbers are page numbers) Weiss Chapter 1 terminology (parenthesized numbers are page numbers) assignment operators In Java, used to alter the value of a variable. These operators include =, +=, -=, *=, and /=. (9) autoincrement

More information

PARAMETRIC POLYMORPHISM

PARAMETRIC POLYMORPHISM PARAMETRIC POLYMORPHISM Java C#! Parametric polymorphism: " Java Generics and Generic C# for.net! The idea: the compiler is able to check parametric classes just looking at their definilon 1 Java Generics

More information

Generics in Java and Beyond

Generics in Java and Beyond Generics in Java and Beyond Martin Buechi 2001 by Martin Büchi 1 Overview Generics Abstraction of generic concepts. C++ templates (STL), parameterized types, ML polymorphic data types and functions, Beta

More information

Example: Count of Points

Example: Count of Points Example: Count of Points 1 public class Point { 2... 3 private static int numofpoints = 0; 4 5 public Point() { 6 numofpoints++; 7 } 8 9 public Point(int x, int y) { 10 this(); // calling Line 5 11 this.x

More information

Parametric Polymorphism for Java: A Reflective Approach

Parametric Polymorphism for Java: A Reflective Approach Parametric Polymorphism for Java: A Reflective Approach By Jose H. Solorzano and Suad Alagic Presented by Matt Miller February 20, 2003 Outline Motivation Key Contributions Background Parametric Polymorphism

More information

On the Algorithm for Specializing Java Programs with Generic Types

On the Algorithm for Specializing Java Programs with Generic Types On the Algorithm for Specializing Java Programs with Generic Types Daniel Selifonov, Nathan Dahlberg, Elena Machkasova Computer Science Discipline University of Minnesota Morris Morris MN, 56267 selif004,dahlb061,elenam@umn.edu

More information

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism Block 1: Introduction to Java Unit 4: Inheritance, Composition and Polymorphism Aims of the unit: Study and use the Java mechanisms that support reuse, in particular, inheritance and composition; Analyze

More information

Object Model. Object Oriented Programming Spring 2015

Object Model. Object Oriented Programming Spring 2015 Object Model Object Oriented Programming 236703 Spring 2015 Class Representation In Memory A class is an abstract entity, so why should it be represented in the runtime environment? Answer #1: Dynamic

More information

Arrays. Chapter Arrays What is an Array?

Arrays. Chapter Arrays What is an Array? Chapter 8 Arrays 81 Arrays 811 What is an Array? To motivate why we might be interested in using arrays, let us implement an app that creates a collection of doubles We will keep track of the number of

More information

CH. 2 OBJECT-ORIENTED PROGRAMMING

CH. 2 OBJECT-ORIENTED PROGRAMMING CH. 2 OBJECT-ORIENTED PROGRAMMING ACKNOWLEDGEMENT: THESE SLIDES ARE ADAPTED FROM SLIDES PROVIDED WITH DATA STRUCTURES AND ALGORITHMS IN JAVA, GOODRICH, TAMASSIA AND GOLDWASSER (WILEY 2016) OBJECT-ORIENTED

More information

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8.

OOPs Concepts. 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8. OOPs Concepts 1. Data Hiding 2. Encapsulation 3. Abstraction 4. Is-A Relationship 5. Method Signature 6. Polymorphism 7. Constructors 8. Type Casting Let us discuss them in detail: 1. Data Hiding: Every

More information

Jam: A Smooth Extension With Java Mixins

Jam: A Smooth Extension With Java Mixins Jam: A Smooth Extension With Java Mixins Davide Ancona, Giovanni Lagorio, Ellena Zucca Presentation created by Left-out Jam abstract syntax Formal definitions of Jam static semantics Formal definitions

More information

Chapter 5 Object-Oriented Programming

Chapter 5 Object-Oriented Programming Chapter 5 Object-Oriented Programming Develop code that implements tight encapsulation, loose coupling, and high cohesion Develop code that demonstrates the use of polymorphism Develop code that declares

More information

Generics method and class definitions which involve type parameters.

Generics method and class definitions which involve type parameters. Contents Topic 07 - Generic Programming I. Introduction Example 1 User defined Generic Method: printtwice(t x) Example 2 User defined Generic Class: Pair Example 3 using java.util.arraylist II. Type

More information

Wrapping a complex C++ library for Eiffel. FINAL REPORT July 1 st, 2005

Wrapping a complex C++ library for Eiffel. FINAL REPORT July 1 st, 2005 Wrapping a complex C++ library for Eiffel FINAL REPORT July 1 st, 2005 Semester project Student: Supervising Assistant: Supervising Professor: Simon Reinhard simonrei@student.ethz.ch Bernd Schoeller Bertrand

More information

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner. HAS-A Relationship Association is a relationship where all objects have their own lifecycle and there is no owner. For example, teacher student Aggregation is a specialized form of association where all

More information

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010 Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages Corky Cartwright Mathias Ricken October 20, 2010 Overview I In OO languages, data values (except for designated non-oo

More information

Idioms for Building Software Frameworks in AspectJ

Idioms for Building Software Frameworks in AspectJ Idioms for Building Software Frameworks in AspectJ Stefan Hanenberg 1 and Arno Schmidmeier 2 1 Institute for Computer Science University of Essen, 45117 Essen, Germany shanenbe@cs.uni-essen.de 2 AspectSoft,

More information

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub Lebanese University Faculty of Science Computer Science BS Degree Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub 2 Crash Course in JAVA Classes A Java

More information

Object Oriented Programming. Java-Lecture 11 Polymorphism

Object Oriented Programming. Java-Lecture 11 Polymorphism Object Oriented Programming Java-Lecture 11 Polymorphism Abstract Classes and Methods There will be a situation where you want to develop a design of a class which is common to many classes. Abstract class

More information

Java Fundamentals (II)

Java Fundamentals (II) Chair of Software Engineering Languages in Depth Series: Java Programming Prof. Dr. Bertrand Meyer Java Fundamentals (II) Marco Piccioni static imports Introduced in 5.0 Imported static members of a class

More information

Object Model. Object Oriented Programming Winter

Object Model. Object Oriented Programming Winter Object Model Object Oriented Programming 236703 Winter 2014-5 Class Representation In Memory A class is an abstract entity, so why should it be represented in the runtime environment? Answer #1: Dynamic

More information

VIRTUAL FUNCTIONS Chapter 10

VIRTUAL FUNCTIONS Chapter 10 1 VIRTUAL FUNCTIONS Chapter 10 OBJECTIVES Polymorphism in C++ Pointers to derived classes Important point on inheritance Introduction to virtual functions Virtual destructors More about virtual functions

More information

Exploring Dynamic Compilation Facility in Java

Exploring Dynamic Compilation Facility in Java Exploring Dynamic Compilation Facility in Java Dingwei He and Kasi Periyasamy Computer Science Department University of Wisconsin-La Crosse La Crosse, WI 54601 kasi@cs.uwlax.edu Abstract Traditional programming

More information

INSTRUCTIONS TO CANDIDATES

INSTRUCTIONS TO CANDIDATES NATIONAL UNIVERSITY OF SINGAPORE SCHOOL OF COMPUTING MIDTERM ASSESSMENT FOR Semester 2 AY2017/2018 CS2030 Programming Methodology II March 2018 Time Allowed 90 Minutes INSTRUCTIONS TO CANDIDATES 1. This

More information

Operators and Expressions

Operators and Expressions Operators and Expressions Conversions. Widening and Narrowing Primitive Conversions Widening and Narrowing Reference Conversions Conversions up the type hierarchy are called widening reference conversions

More information

First IS-A Relationship: Inheritance

First IS-A Relationship: Inheritance First IS-A Relationship: Inheritance The relationships among Java classes form class hierarchy. We can define new classes by inheriting commonly used states and behaviors from predefined classes. A class

More information

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University Day 4 COMP1006/1406 Summer 2016 M. Jason Hinek Carleton University today s agenda assignments questions about assignment 2 a quick look back constructors signatures and overloading encapsulation / information

More information

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus

Types. Type checking. Why Do We Need Type Systems? Types and Operations. What is a type? Consensus Types Type checking What is a type? The notion varies from language to language Consensus A set of values A set of operations on those values Classes are one instantiation of the modern notion of type

More information

CSE P 501 Compilers. Java Implementation JVMs, JITs &c Hal Perkins Winter /11/ Hal Perkins & UW CSE V-1

CSE P 501 Compilers. Java Implementation JVMs, JITs &c Hal Perkins Winter /11/ Hal Perkins & UW CSE V-1 CSE P 501 Compilers Java Implementation JVMs, JITs &c Hal Perkins Winter 2008 3/11/2008 2002-08 Hal Perkins & UW CSE V-1 Agenda Java virtual machine architecture.class files Class loading Execution engines

More information

CS-202 Introduction to Object Oriented Programming

CS-202 Introduction to Object Oriented Programming CS-202 Introduction to Object Oriented Programming California State University, Los Angeles Computer Science Department Lecture III Inheritance and Polymorphism Introduction to Inheritance Introduction

More information

Java Object Oriented Design. CSC207 Fall 2014

Java Object Oriented Design. CSC207 Fall 2014 Java Object Oriented Design CSC207 Fall 2014 Design Problem Design an application where the user can draw different shapes Lines Circles Rectangles Just high level design, don t write any detailed code

More information

Agenda. Objects and classes Encapsulation and information hiding Documentation Packages

Agenda. Objects and classes Encapsulation and information hiding Documentation Packages Preliminaries II 1 Agenda Objects and classes Encapsulation and information hiding Documentation Packages Inheritance Polymorphism Implementation of inheritance in Java Abstract classes Interfaces Generics

More information

More Relationships Between Classes

More Relationships Between Classes More Relationships Between Classes Inheritance: passing down states and behaviors from the parents to their children Interfaces: grouping the methods, which belongs to some classes, as an interface to

More information

An Assertion Checking Wrapper Design for Java

An Assertion Checking Wrapper Design for Java An Assertion Checking Wrapper Design for Java Roy Patrick Tan Department of Computer Science Virginia Tech 660 McBryde Hall, Mail Stop 0106 Blacksburg, VA 24061, USA rtan@vt.edu Stephen H. Edwards Department

More information

Fundamentals of Programming Languages

Fundamentals of Programming Languages Fundamentals of Programming Languages 1. DEFINITIONS... 2 2. BUILT-IN TYPES AND PRIMITIVE TYPES... 3 TYPE COMPATIBILITY... 9 GENERIC TYPES... 14 MONOMORPHIC VERSUS POLYMORPHIC... 16 TYPE IMPLEMENTATION

More information

HAS-A Relationship. If A uses B, then it is an aggregation, stating that B exists independently from A.

HAS-A Relationship. If A uses B, then it is an aggregation, stating that B exists independently from A. HAS-A Relationship Association is a weak relationship where all objects have their own lifetime and there is no ownership. For example, teacher student; doctor patient. If A uses B, then it is an aggregation,

More information

Example: Count of Points

Example: Count of Points Example: Count of Points 1 class Point { 2... 3 private static int numofpoints = 0; 4 5 Point() { 6 numofpoints++; 7 } 8 9 Point(int x, int y) { 10 this(); // calling the constructor with no input argument;

More information

Model Driven Development of Context Aware Software Systems

Model Driven Development of Context Aware Software Systems Model Driven Development of Context Aware Software Systems Andrea Sindico University of Rome Tor Vergata Elettronica S.p.A. andrea.sindico@gmail.com Vincenzo Grassi University of Rome Tor Vergata vgrassi@info.uniroma2.it

More information

Contents. Figures. Tables. Examples. Foreword. Preface. 1 Basics of Java Programming 1. xix. xxi. xxiii. xxvii. xxix

Contents. Figures. Tables. Examples. Foreword. Preface. 1 Basics of Java Programming 1. xix. xxi. xxiii. xxvii. xxix PGJC4_JSE8_OCA.book Page ix Monday, June 20, 2016 2:31 PM Contents Figures Tables Examples Foreword Preface xix xxi xxiii xxvii xxix 1 Basics of Java Programming 1 1.1 Introduction 2 1.2 Classes 2 Declaring

More information

Java Magistère BFA

Java Magistère BFA Java 101 - Magistère BFA Lesson 3: Object Oriented Programming in Java Stéphane Airiau Université Paris-Dauphine Lesson 3: Object Oriented Programming in Java (Stéphane Airiau) Java 1 Goal : Thou Shalt

More information

What s Conformance? Conformance. Conformance and Class Invariants Question: Conformance and Overriding

What s Conformance? Conformance. Conformance and Class Invariants Question: Conformance and Overriding Conformance Conformance and Class Invariants Same or Better Principle Access Conformance Contract Conformance Signature Conformance Co-, Contra- and No-Variance Overloading and Overriding Inheritance as

More information

Efficient Implementation of Run-time Generic Types for Java

Efficient Implementation of Run-time Generic Types for Java Efficient Implementation of Run-time Generic Types for Java Eric Allen, Robert Cartwright, Brian Stoler Rice University 6100 Main St. Houston, TX 11005, USA {eallen, cork, bstoler }@cs.rice.edu Abstract

More information

Implementing Object Equivalence in Java Using the Template Method Design Pattern

Implementing Object Equivalence in Java Using the Template Method Design Pattern Implementing Object Equivalence in Java Using the Template Method Design Pattern Daniel E. Stevenson and Andrew T. Phillips Computer Science Department University of Wisconsin-Eau Claire Eau Claire, WI

More information

Object-Oriented Concepts and Principles (Adapted from Dr. Osman Balci)

Object-Oriented Concepts and Principles (Adapted from Dr. Osman Balci) Object-Oriented Concepts and Principles (Adapted from Dr. Osman Balci) Sung Hee Park Department of Mathematics and Computer Science Virginia State University September 18, 2012 The Object-Oriented Paradigm

More information

Safe Runtime Downcasts With Ownership Types

Safe Runtime Downcasts With Ownership Types Safe Runtime Downcasts With Ownership Types Chandrasekhar Boyapati, Robert Lee, and Martin Rinard Laboratory for Computer Science Massachusetts Institute of Technology 200 Technology Square, Cambridge,

More information

Inheritance (Outsource: )

Inheritance (Outsource: ) (Outsource: 9-12 9-14) is a way to form new classes using classes that have already been defined. The new classes, known as derived classes, inherit attributes and behavior of the pre-existing classes,

More information

Comparison and Analysis to Extending a Existing Programming Language to Support Generics

Comparison and Analysis to Extending a Existing Programming Language to Support Generics Comparison and Analysis to Extending a Existing Programming Language to Support Generics Shu-Chun Weng Computer Science and Software Engineering Department National Taiwan University No.1, Sec. 4, Roosevelt

More information

Tutorial 02: Writing Source Code

Tutorial 02: Writing Source Code Tutorial 02: Writing Source Code Contents: 1. Generating a constructor. 2. Generating getters and setters. 3. Renaming a method. 4. Extracting a superclass. 5. Using other refactor menu items. 6. Using

More information

CSE Lecture 7: Polymorphism and generics 16 September Nate Nystrom UTA

CSE Lecture 7: Polymorphism and generics 16 September Nate Nystrom UTA CSE 3302 Lecture 7: Polymorphism and generics 16 September 2010 Nate Nystrom UTA 2 Polymorphism poly = many morph = shape Allow a variable to contain values with different types 3 Subtype polymorphism

More information

Atelier Java - J1. Marwan Burelle. EPITA Première Année Cycle Ingénieur.

Atelier Java - J1. Marwan Burelle.  EPITA Première Année Cycle Ingénieur. marwan.burelle@lse.epita.fr http://wiki-prog.kh405.net Plan 1 2 Plan 3 4 Plan 1 2 3 4 A Bit of History JAVA was created in 1991 by James Gosling of SUN. The first public implementation (v1.0) in 1995.

More information

Exercise: Singleton 1

Exercise: Singleton 1 Exercise: Singleton 1 In some situations, you may create the only instance of the class. 1 class mysingleton { 2 3 // Will be ready as soon as the class is loaded. 4 private static mysingleton Instance

More information

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Java Generics

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Java Generics 1 CSCE 314: Programming Languages Dr. Flemming Andersen Java Generics 2 Detour: Rules for Method Overriding (1) CSCE 314 TAMU Fall 2017 1. The argument list should be exactly the same as that of the overridden

More information

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language Categories of languages that support OOP: 1. OOP support is added to an existing language - C++ (also supports procedural and dataoriented programming) - Ada 95 (also supports procedural and dataoriented

More information

Configuration Provider: A Pattern for Configuring Threaded Applications

Configuration Provider: A Pattern for Configuring Threaded Applications Configuration Provider: A Pattern for Configuring Threaded Applications Klaus Meffert 1 and Ilka Philippow 2 Technical University Ilmenau plop@klaus-meffert.de 1, ilka.philippow@tu-ilmena.de 2 Abstract

More information

Student Performance Q&A:

Student Performance Q&A: Student Performance Q&A: 2004 AP Computer Science A Free-Response Questions The following comments on the 2004 free-response questions for AP Computer Science A were written by the Chief Reader, Chris

More information

Inheritance. Inheritance allows the following two changes in derived class: 1. add new members; 2. override existing (in base class) methods.

Inheritance. Inheritance allows the following two changes in derived class: 1. add new members; 2. override existing (in base class) methods. Inheritance Inheritance is the act of deriving a new class from an existing one. Inheritance allows us to extend the functionality of the object. The new class automatically contains some or all methods

More information

COP 3330 Final Exam Review

COP 3330 Final Exam Review COP 3330 Final Exam Review I. The Basics (Chapters 2, 5, 6) a. comments b. identifiers, reserved words c. white space d. compilers vs. interpreters e. syntax, semantics f. errors i. syntax ii. run-time

More information

Object-Oriented Programming Paradigm

Object-Oriented Programming Paradigm Object-Oriented Programming Paradigm Sample Courseware Object-Oriented Programming Paradigm Object-oriented programming approach allows programmers to write computer programs by representing elements of

More information

A Static Alternative To Java Dynamic Proxies

A Static Alternative To Java Dynamic Proxies A Static Alternative To Java Dynamic Proxies Abstract The Proxy design pattern is often used in applications, but induces generally an implementation overhead. To simplify the developer work, the Java

More information

The compilation process is driven by the syntactic structure of the program as discovered by the parser

The compilation process is driven by the syntactic structure of the program as discovered by the parser Semantic Analysis The compilation process is driven by the syntactic structure of the program as discovered by the parser Semantic routines: interpret meaning of the program based on its syntactic structure

More information

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance Contents Topic 04 - Inheritance I. Classes, Superclasses, and Subclasses - Inheritance Hierarchies Controlling Access to Members (public, no modifier, private, protected) Calling constructors of superclass

More information

Types and Type Inference

Types and Type Inference CS 242 2012 Types and Type Inference Notes modified from John Mitchell and Kathleen Fisher Reading: Concepts in Programming Languages, Revised Chapter 6 - handout on Web!! Outline General discussion of

More information

PROGRAMMING LANGUAGE 2

PROGRAMMING LANGUAGE 2 31/10/2013 Ebtsam Abd elhakam 1 PROGRAMMING LANGUAGE 2 Java lecture (7) Inheritance 31/10/2013 Ebtsam Abd elhakam 2 Inheritance Inheritance is one of the cornerstones of object-oriented programming. It

More information

Compilation of Object Oriented Languages Tik Compilers Seminar

Compilation of Object Oriented Languages Tik Compilers Seminar Compilation of Object Oriented Languages Burlacu Mihai Helsinki University of Technology burlacum@cc.hut.fi Abstract The paper covers briefly the object-oriented concepts, usability and advantages of using

More information

The Java Type System (continued)

The Java Type System (continued) Object-Oriented Design Lecture 5 CSU 370 Fall 2007 (Pucella) Friday, Sep 21, 2007 The Java Type System (continued) The Object Class All classes subclass the Object class. (By default, this is the superclass

More information

Exercise 12 Initialization December 15, 2017

Exercise 12 Initialization December 15, 2017 Concepts of Object-Oriented Programming AS 2017 Exercise 12 Initialization December 15, 2017 Task 1 Consider a Java class Vector, representing a 2 dimensional vector: public class Vector { public Number!

More information

Polymorphism. return a.doublevalue() + b.doublevalue();

Polymorphism. return a.doublevalue() + b.doublevalue(); Outline Class hierarchy and inheritance Method overriding or overloading, polymorphism Abstract classes Casting and instanceof/getclass Class Object Exception class hierarchy Some Reminders Interfaces

More information

Compiler Construction 2016/2017 Polymorphic Types and Generics

Compiler Construction 2016/2017 Polymorphic Types and Generics Compiler Construction 2016/2017 Polymorphic Types and Generics Peter Thiemann January 8, 2017 Outline 1 Polymorphic Types and Generics 2 Parametric Polymorphism 3 Translation of Polymorphic Programs 4

More information

Casting -Allows a narrowing assignment by asking the Java compiler to "trust us"

Casting -Allows a narrowing assignment by asking the Java compiler to trust us Primitives Integral types: int, short, long, char, byte Floating point types: double, float Boolean types: boolean -passed by value (copied when returned or passed as actual parameters) Arithmetic Operators:

More information

Garbage Collection (2) Advanced Operating Systems Lecture 9

Garbage Collection (2) Advanced Operating Systems Lecture 9 Garbage Collection (2) Advanced Operating Systems Lecture 9 Lecture Outline Garbage collection Generational algorithms Incremental algorithms Real-time garbage collection Practical factors 2 Object Lifetimes

More information

CPS 506 Comparative Programming Languages. Programming Language

CPS 506 Comparative Programming Languages. Programming Language CPS 506 Comparative Programming Languages Object-Oriented Oriented Programming Language Paradigm Introduction Topics Object-Oriented Programming Design Issues for Object-Oriented Oriented Languages Support

More information

Java Overview An introduction to the Java Programming Language

Java Overview An introduction to the Java Programming Language Java Overview An introduction to the Java Programming Language Produced by: Eamonn de Leastar (edeleastar@wit.ie) Dr. Siobhan Drohan (sdrohan@wit.ie) Department of Computing and Mathematics http://www.wit.ie/

More information

UNIT 3 ARRAYS, RECURSION, AND COMPLEXITY CHAPTER 11 CLASSES CONTINUED

UNIT 3 ARRAYS, RECURSION, AND COMPLEXITY CHAPTER 11 CLASSES CONTINUED UNIT 3 ARRAYS, RECURSION, AND COMPLEXITY CHAPTER 11 CLASSES CONTINUED EXERCISE 11.1 1. static public final int DEFAULT_NUM_SCORES = 3; 2. Java allocates a separate set of memory cells in each instance

More information

Lecture Notes on Programming Languages

Lecture Notes on Programming Languages Lecture Notes on Programming Languages 85 Lecture 09: Support for Object-Oriented Programming This lecture discusses how programming languages support object-oriented programming. Topics to be covered

More information

Computer Science 2 Lecture 4 Inheritance: Trinidad Fruit Stand 02/15/2014 Revision : 1.7

Computer Science 2 Lecture 4 Inheritance: Trinidad Fruit Stand 02/15/2014 Revision : 1.7 Computer Science 2 Lecture 4 Inheritance: Trinidad Fruit Stand 02/15/2014 Revision : 1.7 1 Problem Ralph owns the Trinidad Fruit Stand that sells its fruit on the street, and he wants to use a computer

More information

Efficient Separate Compilation of Object-Oriented Languages

Efficient Separate Compilation of Object-Oriented Languages Efficient Separate Compilation of Object-Oriented Languages Jean Privat, Floréal Morandat, and Roland Ducournau LIRMM Université Montpellier II CNRS 161 rue Ada 34392 Montpellier cedex 5, France {privat,morandat,ducour}@lirmm.fr

More information

Distributed Systems Recitation 1. Tamim Jabban

Distributed Systems Recitation 1. Tamim Jabban 15-440 Distributed Systems Recitation 1 Tamim Jabban Office Hours Office 1004 Sunday, Tuesday: 9:30-11:59 AM Appointment: send an e-mail Open door policy Java: Object Oriented Programming A programming

More information

CA Compiler Construction

CA Compiler Construction CA4003 - Compiler Construction Semantic Analysis David Sinclair Semantic Actions A compiler has to do more than just recognise if a sequence of characters forms a valid sentence in the language. It must

More information

WA1278 Introduction to Java Using Eclipse

WA1278 Introduction to Java Using Eclipse Lincoln Land Community College Capital City Training Center 130 West Mason Springfield, IL 62702 217-782-7436 www.llcc.edu/cctc WA1278 Introduction to Java Using Eclipse This course introduces the Java

More information

1 Shyam sir JAVA Notes

1 Shyam sir JAVA Notes 1 Shyam sir JAVA Notes 1. What is the most important feature of Java? Java is a platform independent language. 2. What do you mean by platform independence? Platform independence means that we can write

More information

The list abstract data type defined a number of operations that all list-like objects ought to implement:

The list abstract data type defined a number of operations that all list-like objects ought to implement: Chapter 7 Polymorphism Previously, we developed two data structures that implemented the list abstract data type: linked lists and array lists. However, these implementations were unsatisfying along two

More information

Polymorphic (Generic) Programming in Java

Polymorphic (Generic) Programming in Java Polymorphic (Generic) Programming in Java We have used the fact that Java classes are arranged as a tree with the built in class Object at the root to write generic or polymorphic code such as the following

More information

On Variance-Based Subtyping for Parametric Types

On Variance-Based Subtyping for Parametric Types On Variance-Based Subtyping for Parametric Types Atsushi Igarashi 1 and Mirko Viroli 2 1 Graduate School of Informatics, Kyoto University Yoshida-Honmachi, Sakyo-ku, Kyoto 606-8501, Japan igarashi@kuis.kyoto-u.ac.jp

More information

Harvard School of Engineering and Applied Sciences Computer Science 152

Harvard School of Engineering and Applied Sciences Computer Science 152 Harvard School of Engineering and Applied Sciences Computer Science 152 Lecture 17 Tuesday, March 30, 2010 1 Polymorph means many forms. Polymorphism is the ability of code to be used on values of different

More information

Inheritance and Polymorphism

Inheritance and Polymorphism Inheritance and Polymorphism Dr. M. G. Abbas Malik Assistant Professor Faculty of Computing and IT (North Jeddah Branch) King Abdulaziz University, Jeddah, KSA mgmalik@kau.edu.sa www.sanlp.org/malik/cpit305/ap.html

More information

Practical Mostly-Static Information Flow Control. Andrew Myers MIT Lab for Computer Science

Practical Mostly-Static Information Flow Control. Andrew Myers MIT Lab for Computer Science Practical Mostly-Static Information Flow Control Andrew Myers MIT Lab for Computer Science Privacy Old problem (secrecy, confidentiality) : prevent programs from leaking data Untrusted, downloaded code:

More information

Absolute C++ Walter Savitch

Absolute C++ Walter Savitch Absolute C++ sixth edition Walter Savitch Global edition This page intentionally left blank Absolute C++, Global Edition Cover Title Page Copyright Page Preface Acknowledgments Brief Contents Contents

More information

C++ Important Questions with Answers

C++ Important Questions with Answers 1. Name the operators that cannot be overloaded. sizeof,.,.*,.->, ::,? 2. What is inheritance? Inheritance is property such that a parent (or super) class passes the characteristics of itself to children

More information

Exercise 8 Parametric polymorphism November 18, 2016

Exercise 8 Parametric polymorphism November 18, 2016 Concepts of Object-Oriented Programming AS 2016 Exercise 8 Parametric polymorphism November 18, 2016 Task 1 Consider the following Scala classes: class A class B extends A class P1[+T] class P2[T

More information

Object-Oriented Programming

Object-Oriented Programming Object-Oriented Programming 3/18/14 Presentation for use with the textbook Data Structures and Algorithms in Java, 6th edition, by M. T. Goodrich, R. Tamassia, and M. H. Goldwasser, Wiley, 2014 Object-Oriented

More information

Instantiation of Template class

Instantiation of Template class Class Templates Templates are like advanced macros. They are useful for building new classes that depend on already existing user defined classes or built-in types. Example: stack of int or stack of double

More information

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS PAUL L. BAILEY Abstract. This documents amalgamates various descriptions found on the internet, mostly from Oracle or Wikipedia. Very little of this

More information

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner. HAS-A Relationship Association is a relationship where all objects have their own lifecycle and there is no owner. For example, teacher student Aggregation is a specialized form of association where all

More information

Hypertext A Case Study of Formal Object-Oriented Software Development

Hypertext A Case Study of Formal Object-Oriented Software Development Hypertext A Case Study of Formal Object-Oriented Software Development Andreas Rüping Forschungszentrum Informatik (FZI) Bereich Programmstrukturen Haid-und-Neu-Straße 10-14 D-76131 Karlsruhe e-mail: rueping@fzi.de

More information

Introduction to Programming Using Java (98-388)

Introduction to Programming Using Java (98-388) Introduction to Programming Using Java (98-388) Understand Java fundamentals Describe the use of main in a Java application Signature of main, why it is static; how to consume an instance of your own class;

More information