2. Disclaimer & Acknowledgments
>!Even though Ezequiel Aranda is a full-time employee of Sun
Microsystems, the contents here are created as his own
personal endeavor and thus does not reflect any official
stance of Sun Microsystems.
>!Sun Microsystems is not responsible for any inaccuracies in
the contents.
>!Acknowledgments – The slides of this presentation are made
from “SCJP Unit 1” by Warit Wanwithu and Thanisa
Kruawaisayawan and SCJP Workshop by P. Srikanth.
>!This slides are Licensed under a Creative Commons
Attribution – Noncommercial – Share Alike 3.0
>!http://creativecommons.org/licenses/by-nc-sa/3.0/
3. AGENDA
>! iterales
L
>! eferencias
R
>! rrays
A
>! rappers
W
>! oxing y Widening
B
>! obrecarga con boxing, widening y var-args
S
>! arbage Collection
G
4. Stack y Heap
>! as variables de instancia y los objetos se
L
almeacenan en el heap.
>! as variables locales, en el stack.
L
5. Literales Octales
>!Los enteros octales sólo
utilizan los dígitos del 0 al 7.
>!En Java, se puede
representar un entero en
forma octal colocando un
cero delante del número.
int six = 06; // Equivale a 6
int seven = 07; // Equivale a 7
int eight = 010; // Equivale a 8
int nine = 011; // Equivale a 9
6. Literales Hexadecimales
>! n valor hexadecimal comienza con 0x u OX.
U
>! or Ejemplo:
P
int x = 0X0001;
int y = 0x7fffffff;
int z = 0xDeadCafe;
x = 1 y = 2147483647 z = -559035650
>! XCAFE y 0xcafe son validos y tienen el mismo
0
valor.
7. Literales de punto flotante
>! os literales de punto flotante están definidos
L
como double (64 bits) por defecto, por lo que
al asignar un literal a una variable float (32
bits), debemos colocarle el sufijo F (o f).
float f = 23.467890;
// falla la compilación
float g = 49837849.029847F;
8. Literales de caracter
>! s posible escribirlos como el valor Unicode
E
del caracter, usando el prefijo u.
char letraN= 'u004E'; // la letra
'N'
>! os caracteres son enteros sin signo de 16
L
bits.
char e = -29; // necesitará un cast
char f = 70000 // necesitará un cast
9. Primitivos vs. Referencias
>! sto se llama Referencia:
E
Button b = new Button();
String s = new String();
>! utton b = null;
B
Esto significa que “Button no refiere a ningún
objeto”
10. Asignaciones sobre primitivos
>! e puede asignar un valor a una variable
S
primitiva usando un literal o el resultado de
una expresión.
int x = 7;
int y = x + 2;
int z = x * y;
byte b = 300;¿Esto compila?
11. Asignaciones sobre primitivos (II)
>! yte b = 3; // 3 entra en un
b
byte
>! yte c = 8; // 8 entra en un
b
byte
>! yte d = b + c; //No debería
b
haber problema al sumar dos
bytes, pero ¿funciona? ¿Por
qué?
12. Casts en primitivos
>! os casts (conversiones) pueden ser implícitos
L
o explícitos. Que sea implícito significa que
sucede automáticamente.
>! os casts implícitos se dan al poner un tipo
L
más “pequeño” en un contenedor “más
grande”
>! nt a = 100;
i
>! ong b = a;//cast implícito: un int
l
simpre entra en un long.
13. Casts en primitivos (II)
>! n valor que no cabe en un contenedor más
U
pequeño debe convertirse explícitamente,
indicando que conocemos la posibilidad de
perdida de información.
>!float a = 100.001f;
>! intb = (int) a; //cast explícito, el float
podría perder información.
14. Asignar un literal demasiado grande a
una variable
>! i intentamos asignar un literal demasiado
S
grande a una variable obtendremos un error
de compilación.
float f = 32.3;
byte a = 128;
// byte llega hasta 127
>! Qué pasa si hacemos esto?
¿
byte a = (byte) 128;
15. Asignando una variable primitiva a otra
class ValueTest{
public static void main (String [] args) {
int a = 25; // asignamos un valor a ‘a’
System.out.println(“first a = " + a);
int x = a;
x = 30;
System.out.println(“second a = " + a);
}
}
16. Asignación de variables de referencia
public class Foo{
public void doFooStuff() { }
}
public class Bar extends Foo{
public void doBarStuff() { }
}
class Test {
public static void main (String [] args{
Foo reallyABar= new Bar(); // Legal
Bar reallyAFoo= new Foo(); // Ilegal
}
}
17. Tiempo de vida de las variables
>!Las variables estáticas se crean cuando se carga la clase
y sobreviven mientras la clase se mantenga cargada en
la JVM.
>!Las variables de instancia se crean con cada instancia y
sobreviven hasta que la instancia es removida por el
garbage collector.
>!Las variables locales viven mientras el método al que
pertenecen este en el stack. Más adelante veremos que
pueden estar vivas pero fuera de alcance.
>!Las variables de bloque sólo viven mientras el bloque se
este ejecutando.
18. class Layout {
static int s = 343;
int x1;
{ x1 = 7; int x2 = 5; }
Layout(){
x1 += 8; int x3 = 6;
}
void doStuff() {
int y = 0;
for(int z = 0; z < 4; z++) {
y += z + x1;
}
System.out.println("y ="+y);
}
}
19. Variables de instancia – tipos primitivos
public class BirthDate {
int year; // variable de instancia
public static void main(String [] args) {
BirthDate bd= new BirthDate();
bd.showYear();
}
public void showYear() {
System.out.println("The year is " + year);
}
}
20. Variables de instancia – referencias a objetos
public class Book {
private String title;
public String getTitle() {
return title;
}
public static void main(String [] args){
Book b = new Book();
System.out.println("The title is "+
b.getTitle());
}
}
21. Variables de instancia – referencias a objetos (II)
>!null no es lo mismo que un string vacio. Significa
que la variable no hace referencia a ningún objeto
en el heap.
public class Book {
private String title;
// variable de instancia de referencia
public static void main(String[] args) {
Book b = new Book();
System.out.println(b.title);
String s = b.title.toLowerCase();
// Null pointer Exception
}
}
22. Primitivos Locales
>! as variables locales,
L
incluyendo
primitivos, siempre
deben ser
inicializados antes de
utilizarlos.
>! i intentamos utilizar un primitivo sin
S
inicializar, obtendremos un error de
compilación.
23. Referencias a objetos locales
>!A las referencias locales no se les asigna un valor
por defecto (es decir, no son null por defecto). El
siguiente código no compila:
import java.util.Date;
public class TimeTravel{
public static void main(String[] args) {
Date date; // falla la compilación.
if (date == null)
System.out.println("date es null");
}
}
24. Asignar una variable de referencia a otra
import java.awt.Dimension;
class ReferenceTest{
public static void main (String [] args){
Dimension a = new Dimension(5,10);
System.out.println("a.height = " +
a.height);
Dimension b = a;
b.height = 30;
System.out.println("a.height = " +
a.height +" after change to b");
}
}
25. Asignar una variable de referencia
a otra (II)
>! e declara b, y se le asignan el valor de a. En
S
este punto ambas variables contienen valores
identicos, porque los contenidos de a se
copiaron en b. Aún hay solo un objeto
Dimension, al que tanto a como b hacen
referencia.
>! i asignamos la variable a a b, el patrón de
S
bits en a es copiado, y la nueva copia se
coloca en b.
26. String
>! na excepción a la forma en la que se
U
asignan las referencias a objetos es String.
>! os objetos String son inmutables, no se
L
puede cambiar el valor de un objeto String.
>! iempre que hagamos un cambio en un
S
String, la VM actualizará la variable de
referencia para apuntar a un nuevo objeto.
27. String (II)
>! e crea un nuevo String se crea (o se
S
encuentra uno nuevo en el String Pool),
dejando el original sin modificar.
>! a referencia utilizada para modificar el
L
String se asigna al nuevo objeto.
28. Pasando referencias
>! uando pasamos una variable
C
(referencia a objeto) a un método,
debemos tener en cuenta que estamos
pasando una referencia y no el objeto en
sí mismo.
29. import java.awt.Dimension;
class ReferenceTest{
public static void main (String [] args) {
Dimension d = new Dimension(5,10);
ReferenceTest rt= new ReferenceTest();
System.out.println("Before modify()
d.height = "+ d.height);
rt.modify(d);
System.out.println("After modify()
d.height = "+ d.height);
}
void modify(Dimension dim) {
dim.height = dim.height + 1;
System.out.println("dim = " + dim.height);
}
}
30. class ReferenceTest {
public static void main (String [] args) {
int a = 1;
ReferenceTest rt = new ReferenceTest();
System.out.println("Before = " +a);
rt.modify(a);
System.out.println("After = " + a);
}
void modify(int number) {
number = number + 1;
System.out.println("number = " + number);
}
}
31. Variables de instancia – Arrays
>! n Array es un objeto, por lo tanto una
U
variable de instancia declarada pero no
inicializada explícitamente, tendrá un valor
null.
>! ero… si el Array es inicializado, a todos los
P
elementos que lo componen se les asigna su
valor por defecto.
32. Pregunta
>! qué imprime este código?
¿
public class NewClass{
static int x[];
static int y[] = new int[3];
public int z;
public static void main(String[] args){
System.out.println(x);
System.out.println(y);
System.out.println(y[0]);
System.out.println(x[1]);
System.out.println(z);
}
}
34. Arrays (II)
>!nt[][] scores = {{5,2,4,7}, {9,2}, {3,4}};
i
>! cores[0] // un array de cuatro ints
s
>! cores[1] // un array de dos ints
s
>! cores[2] // un array de dos ints
s
>! cores[0][1] // valor entero 2
s
>! cores[2][1] // valor entero 4
s
35. Arrays (III) – JIT Arrays
public class Foof{
void takesAnArray(int[] someArray) {
// usa el parámetro
}
public static void main (String [] args) {
Foof f = new Foof();
f.takesAnArray(new int[] {7,7,8,2,5});
}
}
36. Arrays de tipos primitivos
>!nt[] weightList= new int[5];
i
>! yte b = 4;
b
>! har c = 'c';
c
>! hort s = 7;
s
>! eightList[0] = b; // OK, byte < int
w
>! eightlist[1] = c; // OK, char < int
w
>! eightList[2] = s; // OK, short < int
w
37. Arrays de referencias a objetos
>! i el tipo declarado para un Array es una
S
clase, dicho Array podrá almacenar objetos de
cualquier subclase del tipo declarado.
class Car {}
class Subaru extends Car {}
class Ferrari extends Car {}
Car [] myCars = {new Subaru(), new
Car(), new Ferrari()};
38. Asignación de Arrays con
referencias a objetos
>! ualquier objeto de una clase que
C
implemente una interfaz pasará la prueba “es
un” (instanceof) para dicha interfaz. Por
ejemplo, si Box implementa Foldable:
Foldable[] foldingThings;
Box[] boxThings= new Box[3];
foldingThings= boxThings;
>! ero no podremos hacer
P
boxThings = foldingThings;
39. Bloques de inicialización
>! n bloque de inicialización estático se ejecuta
U
una única vez, cuando se carga la clase.
>! n bloque de inicialización de instancias se
U
ejecuta cada vez que se crea una instancia.
>! e ejecutan en el orden en el que aparecen.
S
>! os bloques de instancia se ejecutan luego de
L
la llamada a super() en el constructor.
41. ?
static int [] x = new int[4];
static { x[4] = 5; }
>! Funciona?
¿
? ?
42. Wrappers
>! n Java existe un wrapper por cada tipo
E
primitivo (Float de float, Integer de int, etc).
>! odos los wrappers tienen dos constructores
T
(excepto Character): uno que toma un
primitivo del tipo que envuelve y uno que
toma una representación de tipo String del
tipo a construir.
Integer i1 = new Integer(42);
Integer i2 = new Integer("42");
43. Wrappers (II)
>! a clase Character provee un único
L
constructor, que toma un char como
argumento.
Character c1 = new Character('c');
44. Conversión de Wrappers a primitivos
>! uando necesitamos convertir el valor de
C
wrappers a primitivos, podemos usar alguno
de los métodos “____Value()” de esa clase.
Integer i2 = new Integer(42);
byte b = i2.byteValue();
short s = i2.shortValue();
double d = i2.doubleValue();
45. parse____() y valueOf()
>! mbos toman un String como argumento y
A
arrojan una excepción
NumberFormatException si el String no tiene
el formato correcto.
long L2 = Long.parseLong("101010",2); //
String binario a primitivo: L2 = 42
Long L3 = Long.valueOf("101010", 2); //
String binario a objeto Long: L3 value
= 42
46. toString()
>! a idea de este método es obtener una
L
representación coherente de un objeto dado.
>! odos los wrappers poseen un método
T
toString estático sobrecargado que toma un
primitivo del tipo apropiado.
47. AutoBoxing
>! n Java 5 aparece
E
esta característica
conocida como
autoboxing-
autounboxing o
simplemente boxing-
unboxing.
>!int pInt = 420;
>!Integer wInt = pInt; // ‘autoboxing’
>!int p2 = wInt; // ‘auto-unboxing’
48. >!Integer y = new Integer(567);
>!int x = y.intValue(); // unwrap
>!x++; // incremento
>!y = new Integer(x); // re-wrap
>!System.out.println("y= " + y); // print
>!Java 5:
>!Integer y = new Integer(567);
>!y++; // unwrap, incremento,rewrap
>!System.out.println("y= " + y); // print
>!Ambos imprimen: y = 568
49. AutoBoxing (II)
Integer y = 567; // wrapper
Integer x = y;
System.out.println(y==x);
y++; // unwrap, uso, "rewrap"
System.out.println(x + " " + y);
System.out.println(y==x);
50. Boxing, ==, equals()
>! or ahora, sabemos que la intención de
P
equals() es determinar cuando dos instancias
de una clase son “significativamente
equivalentes”.
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2)
System.out.println("different
objects");
if(i1.equals(i2))
System.out.println("meaningfully
equal");
51. Boxing, ==, equals() (II)
>! os instancias de Boolean, Byte, Character
D
(de u0000 a u007f), Short e Integer (-128 a
127) serán == si sus valores primitivos son
iguales.
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4)
System.out.println("same object");
if(i3.equals(i4))
System.out.println("meaningfully
equal");
52. Sobrecarga
>! eamos 3 cosas que pueden hacer la
V
sobrecarga un poco engañosa.
>! idening
W
>! utoBoxing
A
>! ar-args
V
53. Widening
class EasyOver{
static void go(intx) { System.out.print("int"); }
static void go(long x) { System.out.print("long "); }
static void go(double x){ System.out.print("double"); }
public static void main(String [] args) {
byte b = 5;
short s = 5;
long l = 5;
float f = 5.0f;
go(b);
go(s);
go(l);
go(f);
}}// En cada caso, cuando no se encuentra una
correspondencia exacta, la JVM usa el método con el
argumento que cumple con ser el “menor de los más
amplios” que el parámetro.
54. Sobrecarga con Boxing
class AddBoxing {
static void go(Integer x) {
System.out.println("Integer"); }
static void go(long x) {
System.out.println("long"); }
public static void main(String [] args) {
int i = 5;
go(i); // ¿Cuál de los go() se invoca?
}
}
>!El compilador, ¿Decide hacer widening o
autoboxing?
55. Sobrecarga con var-args
class AddVarargs{
static void go(int x, int y) {
System.out.println("int,int");}
static void go(byte... x) {
System.out.println("byte... "); }
public static void main(String[] args){
byte b = 5;
go(b,b); // ¿Cuál de los go() se invoca?
}
}
56. Conclusión
>! l orden en que el compilador elige es el
E
siguiente:
1.! Mismo tipo
2.! Widening
3.! Boxing
4.! Var-args
57. Widening de referencias
class Animal {static void eat() { } }
class Dog3 extends Animal {
public static void main(String[] args) {
Dog3 d = new Dog3();
d.go(d); // ¿Esto vale?
}
void go(Animal a) { }
}
>! l compilador “ensancha” la referencia de
E
Dog3 a Animal, y la invocación funciona
correctamente. La clave es que el widening
de referencias depende de la herencia.
58. Sobrecarga combinando widening y
boxing
>! a regla es que el compilador puede ajustar
L
una invocación siempre y cuando sólo
requiera una única conversión.
class WidenAndBox{
static void go(Long x) {
System.out.println("Long"); }
public static void main(String [] args)
{
byte b = 5;
go(b); // requiere widening y boxing -
ilegal
}}
59. Sobrecarga combinando Boxing y
Widening
class BoxAndWiden {
static void go(Object o) {
Byte b2 = (Byte) o;
System.out.println(b2);
}
public static void main(String [] args) {
byte b = 5;
go(b); // ¿Puede este byte volverse un
object?
}
}
>! Funciona? ¿Por qué?
¿
60. Sobrecarga combinando con Var-args
class Vararg{
static void wide_vararg(long... x)
{System.out.println("long...");}
static void box_vararg(Integer... x)
{System.out.println("Integer...");}
public static void main(String [] args) {
int i = 5;
wide_vararg(5,5); // widening y var-args
box_vararg(5,5); // boxing y var-args
}
}
61. class Eggs {
int doX(Long x, Long y) { return 1; }
int doX(long... x) { return 2; }
int doX(Integer x, Integer y) { return 3; }
int doX(Number n, Number m) { return 4; }
public static void main(String[] args) {
new Eggs().go(); }
void go() {
short s = 7;
System.out.print(doX(s,s) + " ");
System.out.println(doX(7,7));
} }
>! Cuál es el resultado?
¿
A. 1 1 B. 2 1 C. 3 3 D. 4 3
62. Resumen
>! l widening de primitivos usa el tipo más
E
pequeño posible.
>! oxing y Var-args, usados individualmente,
B
son compatibles con sobrecarga.
>! o se puede ensanchar de un wrapper a otro.
N
>! idening -> Boxing = falla
W
>! oxing -> Widening = funciona
B
>! uede combinarse Var-args con widening o
P
boxing.
63. Garbage Collection
>! n C, C++ y otros lenguajes, el programador
E
es responsable de la administración de
memoria.
>! n Java, se provee un hilo de sistema que se
E
encarga de esta tarea.
64. Garbage Collection (II)
>! urante los ciclos ociosos de la JVM, el
D
garbage collector revisa y libera la memoria
que este en condiciones de ser liberada.
>! Elegible” significa que puede ser
“
recolectado.
>! olo podemos pedir el garbage collector
S
usando System.gc();
>! o puede forzarse, sino más bien, sugerirse.
N
65. Garbage Collection (III)
>! n el examen tendremos que identificar
E
cuales objetos son “elegibles” para ser
recolectados.
>! a clave es encontrar los objetos que refieren
L
a NULL.
66.
67. class CardBoard{
Short story = 5;
CardBoard go(CardBoard cb) {
cb= null;
return cb; }
public static void main(String[] args) {
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// do Stuff
} }
>!Cuando llegamos a “//do Stuff”, ¿Cuantos elementos son
elegibles para gc?
A. 0 B. 1 C. 2 D. no compila E. Excepción