2. Generics
Consentono di definire oggetti per i quali non 竪 conosciuto
a priori il tipo (generico) sul quale saranno istanziati. Un
esempio tipico 竪 quello dei container di oggetti (es. le
Collection)
ArrayList<String> gList=new ArrayList<String>();
gList.add(new String("stringa1"));
s=gList.iterator().next(); // non necessario il cast
ArrayList oList=new ArrayList();
oList.add(new String("stringa2"));
s=(String)oList.iterator().next();
3. Generics
Definizione di una classe Generic
package generics;
import java.util.Vector;
public class MyGeneric<E>
{
private Vector<E> vect=new Vector<E>();
public void add(E elem)
{
vect.add(elem);
}
public void print()
{
for(Object e:vect) // new for loop
{
System.out.println(e);
}
}
}
MyGeneric<Integer> my=new
MyGeneric<Integer>();
my.add(new Integer(1));
my.print();
MyGeneric<String> my2=new
MyGeneric<String>();
my2.add(new String("ciao!"));
my2.print();
4. Generics
Wildcard : Permette di dichiarare un oggetto Generic di tipo
ancora non conosciuto
void print(Collection<?> c)
{
for(Object e:c)
{
System.out.println(e);
}
}
Collection<?> c=null;
ArrayList oList=new ArrayList();
c=oList;
5. Generics
Bounded Wildcard : Permette di dichiarare un oggetto
Generic derivante da una specifica classe
public abstract class Shape
{}
public class Circle extends Shape
{}
public class Rectangle extends Shape
{}
void printAll(List<Shape> list)
{} // non 竪 possibile passare una List<Circle> o List<Rectangle>
void printAll(List<? Extends Shape> list)
// 竪 possibile passare oggetti che derivano da Shape
Map<K,V> : esempio di tipo generico con 2 argomenti
addRegisty(Map<String,? Extends Person) {} // Bunded WildCard
6. Generics
Metodi Generici
static <T> void fromArrayToCollection(T[] a, Collection<T> c)
{
for(T e:a)
c.add(e);
}
In questo caso viene generalizzato sia larray che la
Collection
Nei casi in cui si decide di ri-scrivere alcune classi/metodi rendendole
Generics, nella ri-compilazione dei client di tali classi avremo degli
unchecked warning (alternativa compilare i client usando 1.4 flag) .
ArrayList x=new ArrayList();
String[] arr={new String("a"),new String("b"),new String("c")};
fromArrayToCollection(arr, x);
7. Generics
Metodi Generici
E possibile definire un metodo generico utilizzando una
wildcard
Class Collection{
public static <T> void copy(List<T> dest,
List<? extends T> src)
{ .. }
}
Da notare in questo caso la dipendenza tra oggetti: un oggetto di src
deve essere assegnabile ad un oggetto di dest. Un altro modo per
definire tale metodo 竪 il seguente:
Class Collection{
public static <T,S extends T> void copy(List<T> dest,
List<S> src)
{ .. }
}
8. Generics
Tutte le istanze di una classe Generic hanno in comune la
medesima run-time class
ArrayList<String> l1=new ArrayList<String>();
ArrayList<Integer> l2=new ArrayList<Integer>();
System.out.printl(l1.getClass()==l2.getClass()); // true
quindi non ha senso
Collection cs=new ArrayList<String>();
if (cs instanceof ArrayList<String>)
9. Generics
Array
List<?>[] lsa=new List<?>[10]; // ok, array di tipo non definito
Object o=lsa;
Object[] oa=(Object[]) o;
List<Integer>=new ArrayList<Integer>;
li.add(new Integer(3));
oa[1]=li;
String s=(String)lsa[1].get(0); // Run-time error con cast
esplicito
List<String>[] lsa=new List<?>[10]; // unchecked warnings - unsafe
Object[] oa=(Object[]) o;
List<Integer>=new ArrayList<Integer>;
li.add(new Integer(3));
oa[1]=li;
String s=sa[1].get(0); // Run-time error; ma con warning in fase
di compilazione
10. Generics
java.lang.Class
Dal JDK1.5 竪 una classe gerica. Questo implica che il
tipo String.classe 竪 Class<String>, il tipo
Serializzable.class 竪 Class<Serializable>..in
particolare il metodo newIstance() della classe Class
ritorna T.
11. Autoboxing/Inboxing
E la nuova facility che elimina la conversione manuale
tra tipi primitivi e tipi wrapper
int ix=5;
Integer Ix=ix;
int sx=Ix;
12. Enums
E possibile (finalmente !) creare dei tipi di tipo enum
public enum Season { WINTER, SPRING, SUMMER, FALL }; // Genera
un .class
Season en=Season.WINTER; // nella stessa classe
private MyClassDef.Season x; // in unaltra classe
13. Static Import
Consente di accedere a membri statici di una classe senza
ri-specificare la classe
import static java.lang.Math.PI; oppure import static
java.lang.Math.*;
double r = cos(PI * theta);
14. Annotazioni
Consentono linserimento di meta-dati allinterno del
codice.
Definizione di una annotazione:
package annotation;
public @interface Developer{
String name();
String surname();
int eta();
String address() default unassigned;
}
15. Annotazioni
Esistono due tipi di meta-annotazioni che vengono utilizzate per indicare il
contesto in cui lannotazione deve essere applicata e la porzione di codice a
cui si riferisce.
@Retention:
RetentionPolicy.SOURCE // no run-time (JVM) e compilazione
RetentionPolicy.CLASS // compilazione
RetentionPolicy.RUNTIME // solo run-time
@Target:
ElementType.TYPE // class,interface,enum
ElementType.FIELD
ElementType.METHOD
ElementType.PARAMETER
ElementType.CONSTRUCT
ElementType.LOCAL_VARIABLE
ElementType.ANNOTATION_TYPE
ElementType.PACKAGE
16. Annotazioni
Le meta-annotazioni possono essere inserite nella definzione della stessa
annotazione
package annotation;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target (ElementType.METHOD)
public @interface Developer{
String name();
String surname();
int eta();
String address() default unassigned;
}
17. Annotazioni
Applicazione di una annotazione
@Developer(name="Antonio",surname="Furone",eta=37,address="Via
Pescara")
void print(Collection<?> c)
{
for(Object e:c)
{
System.out.println(e);
}
}
18. Annotazioni
Per verificare lesistenza di una annotazione Nel caso specifico data una
classe vengono richiamati solo i metodi della classe sui quali 竪 applicata
lannotazione Test.
import java.lang.reflect.*;
public class RunTests {
public static void main(String[] args) throws Exception
{
int passed = 0, failed = 0;
for (Method m : Class.forName(args[0]).getMethods()) {
if (m.isAnnotationPresent(Test.class)) {
try {
m.invoke(null); passed++; }
catch (Throwable ex) {
System.out.printf("Test %s failed: %s %n", m, ex.getCause()); failed++; }
}
}
System.out.printf("Passed: %d, Failed %d%n", passed, failed);
}
}
19. Annotazioni
APT (Annotation Processing Tool)
E una command-line utility che consente di trovare ed eseguire annotation
processor basati su annotazioni presenti in un set di file sorgenti
Per scrivere un annotation processor 竪 necessario utilizzare i seguenti
packages:
com.sun.mirror.apt: interfaces to interact with the tool
com.sun.mirror.declaration: interfaces to model the source code declarations of fields, methods, classes, etc.
com.sun.mirror.type: interfaces to model types found in the source code
com.sun.mirror.util: various utilities for processing types and declarations, including visitors
Ciascun processor implementa linterfaccia AnnotationProcessor quindi il
metodo process. Listanza di un process 竪 ritornata da una corrispondente
factory AnnotationProcessorFactory. L apt richiama il metodo
getProcessorFor per ottenere il processor passando un
AnnotationProcessorEnvironment
20. Annotazioni
APT (Annotation Processing Tool) - AnnotationProcessorFactory
public class MyAnnotationProcessorFactory implements AnnotationProcessorFactory {
public Collection<String> supportedAnnotationTypes() {
return annotations;
}
public AnnotationProcessor getProcessorFor(Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new MyAnnotationProcessor( env );
}
public Collection<String> supportedOptions() {
return Collections.emptyList();
}
private static ArrayList<String> annotations = new ArrayList<String>();
{
annotations.add( MyAnnotation.class.getName() );
}
}
22. Annotazioni
APT (Annotation Processing Tool) - AnnotationProcessor
public class MyAnnotationProcessor implements AnnotationProcessor
{
public MyAnnotationProcessor(AnnotationProcessorEnvironment env) {
_env = env;
}
public void process() {
Messager messager = _env.getMessager();
File sourceFile = null;
ArrayList<ConditionStatement> csList = new ArrayList<ConditionStatement>();
// obtain the declaration of the annotation we want to process
AnnotationTypeDeclaration annoDecl =
(AnnotationTypeDeclaration)_env.getTypeDeclaration(MyAnnotation.class.getName());
// get the annotated types
Collection<Declaration> annotatedTypes = _env.getDeclarationsAnnotatedWith(annoDecl);
}
}
La compiliazione di tali classi e lesecuzione viene effettuata tramite lapt tool.
23. Monitoring and Management
JVM
Include strumenti (built-in) per il monitoring e il management tramite accesso
locale e/o remoto. La JVM include un MBean Server (management agent) che
applicazioni JMX possono utilizzare;
Package java.lang.management
N.Ro di classi caricate, thread attive, memoria utilizzata, GC statistiche,
Tools
jconsole: tool multi-piattaforma, JMX compilant; modalit locale e remota);
jps: JVM Process Status Tool ;
jstat: JVM Statistics Monitoring Tool Colleziona statistiche di
performance;
jstatd: JVM jstat daemon (RMI server).
24. Monitoring and Management
MBean Server : Un repository di MBeans che consentono il monitoring e il management delle
applicazioni. Implementa linterfaccia javax.management.MBeanServer;
Nel JDK1.5 viene introdotto il platform MBean server, un MBeanServer bult-in nella JVM
accessibile a tutti i componenti in esecuzione (ManagementFactory.getRuntimeMXBean());
Una management application pu嘆 accedere al platform MBean Server in tre diversi modi:
ManagementFactory (direct)
RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
String vendor = mxbean.getVmVendor();
Usando un MBean proxy (direct)
MBeanServerConnection mbs;
...
// Get a MBean proxy for RuntimeMXBean interface
RuntimeMXBean proxy =
ManagementFactory.newPlatformMXBeanProxy(mbs,
ManagementFactory.RUNTIME_MXBEAN_NAME,
RuntimeMXBean.class);
String vendor = proxy.getVmVendor();
Usando una MBean server connection (indirect)
MBeanServerConnection mbs;
...
try {
ObjectName oname = new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
String vendor = (String) mbs.getAttribute(oname, "VmVendor");
} catch (....) {
// Catch the exceptions thrown by ObjectName constructor
// and MBeanServer.getAttribute method
...
}
25. Monitoring and Management
A partire da un ManagementFactory 竪 possibile ottenere degli MXBean attraverso delle
management interface (es.):
ClassLoadingMXBean (java.lang:type=ClassLoading);
RuntimeMXBean (java.lang:type=Runtime);
MemoryMXBean (java.lang:type=Memory);
Esempio di attivazione di VM con JMX agent:
java -Dcom.sun.management.jmxremote.port=1090
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-jar <JDK_HOME>/demo/jfc/Java2D/Java2Demo.jar
Connessione:
try { JMXServiceURL url = new JMXServiceURL("rmi", "", 0, /jndi/rmi://localhost:1090/jmxrmi);
this.jmxc = JMXConnectorFactory.connect(url);
this.server = jmxc.getMBeanServerConnection();
} catch (MalformedURLException e) {
// should not reach here
} catch (IOException e) {
System.err.println("nCommunication error: " + e.getMessage());
System.exit(1);
}
}