Download Capitulo 10 - WordPress.com
Document related concepts
no text concepts found
Transcript
Resumen SCJP Development Compilando con javac El comando javac es usado para invocar al compilador java. La estructura del comando es: javac [options] [source files] Tamto option como sourcefiles son opcionales y ambas permiten multiples entradas EJ javac -help javac -classpath com:. -g Foo.java Bar.java Compilando con –d Por default el compilador pone el archivo .class en el mismo directorio que el .java. La opcion –d permite setearle al compilador en que directorio poner los .class generados. El siguiente comando emitido desde el directorio myProject, compilara la clase MyClass.java y pondra el MyClass.class resultante en el directorio classes. cd myProject javac -d classes source/MyClass.java Supongamos que tenemos el siguiente archive .java en la siguiente estructura de directorios. package com.wickedlysmart; public class MyClass { } EL siguiente commando pondria el .class en el directorio classes/com/wickedlysmart Debido a que MyClass.java esta en un package el compilador reconoce que tiene que poner el .class en el directorio classes/com/wickedlysmart. Si el direcotirio destino que se especifica no existe, habra un eror de compilación, si en el ej previo el directorio classes no existe el compilador tirara error. Comando java EL comando java es usado para invocar a la maquina virtual. java [options] class [args] options y args son opcionales, y pueden tener ambas multiples valores. Se debe especificar exactamente un archivo .class para ejecutar. Este comando asume que es un .class , no es necesario especificarlo. java -DmyProp=myValue MyClass x 1 Si especificamos un .java tirarar un excepcion ClassDefFoundError Usando System properties Java 5, tiene una clase llamada java.uitl.Properties que puede ser usada para acceder a información del sistema persistente tal como la version actual del SO, rl compilador java, y la JVM. Ademas puedes agregar tus propias propiedades. import java.util.*; public class TestProps { public static void main(String[] args) { Properties p = System.getProperties(); p.setProperty("myProp", "myValue"); p.list(System.out); } } If this file is compiled and invoked as follows: java -DcmdProp=cmdVal TestProps You'll get something like this: ... os.name=Mac OS X myProp=myValue ... java.specification.vendor=Sun Microsystems Inc. user.language=en java.version=1.5.0_02 ... cmdProp=cmdVal ... Cuando usas la opcion –D, si el valor contien espacios en blancos el valor entero deberia ser colocado en comillas: java -DcmdProp="cmdVal take 2" TestProps Cuando se usa –D la pareja name=value debe estar junta no debe haver espacios en blanco. El metodo getProperty() es usado para recuperar una propiedad. Puede ser invocado con un argumento (un string que representa el nobre o clave), o puede ser invocado con dos argumentos (un string q representa la clave, y un valor por default string para ser usado como la propiedad si la propiedad no existe), en ambos casos retorna la propiedad como un string. Particularidades sobre el metodo main static public void main(String[] args) public static void main(String... x) static public void main(String bang_a_gong[]) Los ej anteriores son declaraciones legales del metodo main Buscando otras clases Ambos java y javac usan el mismo algoritmo de busqueda: Ambos tienen la misma lista de directorios en donde ellos buscan, las clases. Ambos buscan a travez de la lista de directorios en el mismo orden. Tan pronto encuentran la clase que estan buscando, ellos dejan de buscar. En el caso que sus listas de busqueda contengan dos o mas archivos con el mismo nombre el primerop mque se encontro, sera el que se usara. El primer lugar en donde buscan es en los directorios que contienen las clases que vieene en el estándar J2SE. EN segundo lugar se busca en los directorios definidos por el classpaths. El classpaths contiene listas de directorios. Hay 2 lugares donde el classpath puede ser declarado. UN classpaths puede ser declarado como una variable de ambiente del sistema operativo, el classpath declarado de esta manera es usado por default, aun cuando java o javac sean invocados. UN classpaths puede ser declarado como una opcion en la linea de comnados para java o javac. El classpath declarado de esta manera sobrescribe el classpaths declarado como una variable de ambiente, pero solo persiste por la longitud de la invocación. Declarando y uisando classpaths Classpaths consiste de un numero variable de ubicación de directorios, separados por delimitadores. -classpath /com/foo/acct:/com/foo Es importante recordar que cuando se especifica un subdirectorio, no se esta especificando el directorio superior a el. Por ej, en el ej precendente el directorio /com no se buscara. Cuando se buscan archivos .class , el java y javac comandos no buscan en el directorio actual por defecto, se le debe decir para buscar alli. La manera de decirle al java o javac para buscar en el directorio actual es agregar un “.” Al claspaths. -classpath /com/foo/acct:/com/foo:. Recordar que lo anterior es para archivos class, cuando se le dice al javac que archivos compilar, javac mira en el directorio actual por default. Es importante recordar que en el classpaths se busca de izquierda a derecha. Por lo tanto en una situación donde clases con nombres duplicados son localizados en diferentes directorios en el classpaths, diferentes resultados pueden ocurrir. -classpath /com:/foo:. is not the same as -classpath .:/foo:/com El comando java permite abreviar –classpath con –cp Packages and Searching package com.foo; public class MyClass { public void hi() { } } La clase MyClass es un miembro del package com.foo. Esto significa que el nombre qualificado es com.foo.MyClass. import com.foo.MyClass; // either import will work import com.foo.*; public class Another { void go() { MyClass m1 = new MyClass(); // alias name com.foo.MyClass m2 = new com.foo.MyClass(); // full name m1.hi(); m2.hi(); } } Para encontrar una clase en un package, tenemos que tener un directorio en nuestro classpaths que tenga el package mas a la izquierda (el package root) como subdirectorio. import com.wickedlysmart.Utils; class TestClass { void doStuff() { Utils u = new Utils(); // simple name u.doX("arg1", "arg2"); com.wickedlysmart.Date d = new com.wickedlysmart.Date(); // full name d.getMonth("Oct"); } } Cuando es el tiempo de compìlar o correr TestClass, el classpath debe tener un directorio con los siguientes atributos. Un subdirectorio llamado com (el package root) Un subdirectorio en com llamado wickelysmart Dos archivos en wickelysmart llamados Utils.class y Date.class Finalmente el directorio que tiene estos atributos debe ser accesible (via classpaths) En alguna de las siguientes dos maneras. 1. El path del directorio debe ser absoluto, en otras palabras desde el root. 2. El path del directorio es relativo al directorio actual. Paths relativos y Absolutos Un clasppaths es una colección de uno o mas paths, cada path en un classpath es o relativo o absoluto. Los paths absolutos en unix empiezan con / y en Windows con C:\ . Significa que esta comenzando dede el directorio trot del sistema, que comienze desde el root no significa que el directorio actual es un directorio absoluto y siempre el mismo. Un path relativo es alguno que no comienza con un slash. Ej de directorio full y un classpaths. -cp dirB:dirB/dirC En este ej, dirB y dirB/dirC son paths relativos, ambos de estos paths son significativos cuando el directorio actual es dirA. Si el directorio actual es dirA, y se esta buscando archivos class, y se usa el classpaths anterior, en cual directorios se buscara’ Cuando el directorio actual es dirA, luego en dirB y dirC se buscara, pero no en dirA. Si el directorio actual es el root, ya que dirB no es un subdirectorio directo de root, en ninguno se buscara. Si el directorio actual es dirB, tambien en ninguno se buscara. In this case, what directories will be searched if the current directory is dirA? How about if the current directory is root? How about if the current directory is dirB? In this case, both paths in the classpath are absolute. It doesn't matter what the current directory is; since absolute paths are specified the search results will always be the same. Specifically, only dirC will be searched, regardless of the current directory. The first path (/dirB) is invalid since dirB is not a direct subdirectory of root, so dirB will never be searched. And, one more time, for emphasis, since dot (.) is not in the classpath, the current directory will only be searched if it happens to be described elsewhere in the classpath (in this case, dirC). Archivos Jar Se puede crear un archive jar que contenga todos los archivos class de myApp, y tambien mantener la estructura de directories de myApp. Una vez que este archivo jar es creado, este puede ser movido de un lugar a otro, de una maquina a otra, y todas las clases en el jar ser accedidas via classpaths, y usadas por java y javac. Todo esto puede ser echo sin descomprimir el jar. Encontrar un archivo Jar usando classpaths es similar a encontrar un archivo package en el classpath. La diferencia es que cuando se especifica el camino al archivo jar, se debe incluir el nombre del archivo jar al final del path. Por ej si queremos compilar UseStuff.java en el directorio test, y UseStuff.java necesita acceder a una clase contenida en myApp.jar. Para compilar UseStuff.java se deberia hacer, cd test javac -classpath ws/myApp.jar UseStuff.java Comparando el uso de archivos jar para usar en el classpath en vez de usar una class de un package. Si UseStuff.java necesita usar clases del package myApp.utils y la clase no esta en un jar se deberia hacer: cd test javac -classpath ws UseStuff.java Recordar que cuando usamos classpath el ultimo directorio del path debe ser el directorio superior del directorio root para el package (en el ej precedente myApp es el directorio root de el package myApp.Utils. Nota: Cuando se usa una sentencia import se esta declarando unicamente un package. Cuando se dice import java.util.* quiere decir “usar el nombre corto para todas las clases en el package java.util. No estamos consiguiendo las clases de los packages java.util.jar o del java.util.regex . Estos packages son independientes de los otros, lo unico que ellos comparen el es mismo directorio root. Como conclusión no se puede decir por ej impor.java.* y pensar que se esta importando multiples packages, solo recordar una sentencia import puede importar solo un package. Usando ../jre/lib/ext con archivos jar Muy oculto dentro de nuestro directorio java hay un subdirectorio llamado jre/lib/ext. Si colocamos archivos jar ahí java y javac podran encontrarlos, y usar los archivos class que ellos contengan. No se tienen que mencionar este subdirectorio en el classpath. Es posible crear varieables de ambiente que proveen un alias para grandes classpath. Usando import static Import Static Los import static pueden ser usados cuando queremos usar miembros static de una clase. Antes de import static public class TestStatic { public static void main(String[] args) { System.out.println(Integer.MAX_VALUE); System.out.println(Integer.toHexString(42)); } } Despues de import static import static java.lang.System.out; // 1 import static java.lang.Integer.*; // 2 public class TestStaticImport { public static void main(String[] args) { out.println(MAX_VALUE); // 3 out.println(toHexString(42)); // 4 } } La sintaxis debe ser import static, seguida por el nombre cualificado del miembro static que se quiere importar o un wildcard. Reglas para import static: Se debe decir import static y no static import Mirar por si existe import ambiguos, por ej si se hace un import static para la clase Long y la clase Integer, referirnos al MAX_VALUE causara error de compilación, debido a que Integer y Long pooseen MAX_VALUE. Se puede hacer un import static de una referncia a un objeto static, constantes (recordar que son static y final) y metodos static.