Sei sulla pagina 1di 68

SCJP 6

Clase 3 Asignaciones

Ezequiel Aranda
Sun Microsystems Campus
Ambassador

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/

AGENDA
>Literales
>Referencias
>Arrays
>Wrappers
>Boxing y Widening
>Sobrecarga con boxing, widening y var-args
>Garbage Collection

Stack y Heap

>Las variables de instancia y los objetos se


almeacenan en el heap.
>Las variables locales, en el stack.

Literales Octales
>Los enteros octales slo
utilizan los dgitos del 0 al 7.
>En Java, se puede
representar un entero en
forma octal colocando un
cero delante del nmero.
int
int
int
int

six = 06; // Equivale a 6


seven = 07; // Equivale a 7
eight = 010; // Equivale a 8
nine = 011; // Equivale a 9

Literales Hexadecimales
>Un valor hexadecimal comienza con 0x u OX.
>Por Ejemplo:
int
int
int
x =

x
y
z
1

=
=
=
y

0X0001;
0x7fffffff;
0xDeadCafe;
= 2147483647 z = -559035650

>0XCAFE y 0xcafe son validos y tienen el mismo


valor.

Literales de punto flotante


>Los literales de punto flotante estn definidos
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 compilacin
float g = 49837849.029847F;

Literales de caracter
>Es posible escribirlos como el valor Unicode
del caracter, usando el prefijo \u.
char letraN= '\u004E'; // la letra
'N'

>Los caracteres son enteros sin signo de 16


bits.
char e = -29; // necesitar un cast
char f = 70000 // necesitar un cast

Primitivos vs. Referencias


>Esto se llama Referencia:
Button b = new Button();
String s = new String();
>Button b = null;
Esto significa que Button no refiere a ningn
objeto

Asignaciones sobre primitivos


>Se puede asignar un valor a una variable
primitiva usando un literal o el resultado de
una expresin.
int x = 7;
int y = x + 2;
int z = x * y;
byte b = 300;Esto compila?

Asignaciones sobre primitivos (II)


>byte b = 3; // 3 entra en un
byte
>byte c = 8; // 8 entra en un
byte
>byte d = b + c; //No debera
haber problema al sumar dos
bytes, pero funciona? Por
qu?

Casts en primitivos
>Los casts (conversiones) pueden ser implcitos
o explcitos. Que sea implcito significa que
sucede automticamente.
>Los casts implcitos se dan al poner un tipo
ms pequeo en un contenedor ms
grande
>int a = 100;
>long b = a;//cast implcito: un int
simpre entra en un long.

Casts en primitivos (II)


>Un valor que no cabe en un contenedor ms
pequeo debe convertirse explcitamente,
indicando que conocemos la posibilidad de
perdida de informacin.
>float a = 100.001f;
> intb = (int) a; //cast explcito, el float
podra perder informacin.

Asignar un literal demasiado grande a


una variable
>Si intentamos asignar un literal demasiado
grande a una variable obtendremos un error
de compilacin.
float f = 32.3;
byte a = 128;
// byte llega hasta 127

>Qu pasa si hacemos esto?


byte a = (byte) 128;

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);
}
}

Asignacin 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
}
}

Tiempo de vida de las variables


>Las variables estticas 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 mtodo al que
pertenecen este en el stack. Ms adelante veremos que
pueden estar vivas pero fuera de alcance.
>Las variables de bloque slo viven mientras el bloque se
este ejecutando.

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);
}
}

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);
}
}

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());
}
}

Variables de instancia referencias a objetos (II)


>null no es lo mismo que un string vacio. Significa
que la variable no hace referencia a ningn 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
}
}

Primitivos Locales
>Las variables locales,
incluyendo
primitivos, siempre
deben ser
inicializados antes de
utilizarlos.
>Si intentamos utilizar un primitivo sin
inicializar, obtendremos un error de
compilacin.

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 cdigo no compila:
import java.util.Date;
public class TimeTravel{
public static void main(String[] args) {
Date date; // falla la compilacin.
if (date == null)
System.out.println("date es null");
}
}

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");
}
}

Asignar una variable de referencia


a otra (II)

>Se declara b, y se le asignan el valor de a. En


este punto ambas variables contienen valores
identicos, porque los contenidos de a se
copiaron en b. An hay solo un objeto
Dimension, al que tanto a como b hacen
referencia.
>Si asignamos la variable a a b, el patrn de
bits en a es copiado, y la nueva copia se
coloca en b.

String
>Una excepcin a la forma en la que se
asignan las referencias a objetos es String.
>Los objetos String son inmutables, no se
puede cambiar el valor de un objeto String.
>Siempre que hagamos un cambio en un
String, la VM actualizar la variable de
referencia para apuntar a un nuevo objeto.

String (II)
>Se crea un nuevo String se crea (o se
encuentra uno nuevo en el String Pool),
dejando el original sin modificar.
>La referencia utilizada para modificar el
String se asigna al nuevo objeto.

Pasando referencias
>Cuando pasamos una variable
(referencia a objeto) a un mtodo,
debemos tener en cuenta que estamos
pasando una referencia y no el objeto en
s mismo.

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);
}
}

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);
}
}

Variables de instancia Arrays


>Un Array es un objeto, por lo tanto una
variable de instancia declarada pero no
inicializada explcitamente, tendr un valor
null.
>Pero si el Array es inicializado, a todos los
elementos que lo componen se les asigna su
valor por defecto.

Pregunta
>qu imprime este cdigo?
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);
}
}

Arrays
>int[][] myArray= new int[3][]; // Legal

Arrays (II)
>int[][] scores = {{5,2,4,7}, {9,2}, {3,4}};
>scores[0] // un array de cuatro ints
>scores[1] // un array de dos ints
>scores[2] // un array de dos ints
>scores[0][1] // valor entero 2
>scores[2][1] // valor entero 4

Arrays (III) JIT Arrays


public class Foof{
void takesAnArray(int[] someArray) {
// usa el parmetro
}
public static void main (String [] args) {
Foof f = new Foof();
f.takesAnArray(new int[] {7,7,8,2,5});
}
}

Arrays de tipos primitivos


>int[] weightList= new int[5];
>byte b = 4;
>char c = 'c';
>short s = 7;
>weightList[0] = b; // OK, byte < int
>weightlist[1] = c; // OK, char < int
>weightList[2] = s; // OK, short < int

Arrays de referencias a objetos


>Si el tipo declarado para un Array es una
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()};

Asignacin de Arrays con


referencias a objetos
>Cualquier objeto de una clase que
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;

>Pero no podremos hacer


boxThings = foldingThings;

Bloques de inicializacin
>Un bloque de inicializacin esttico se ejecuta
una nica vez, cuando se carga la clase.
>Un bloque de inicializacin de instancias se
ejecuta cada vez que se crea una instancia.
>Se ejecutan en el orden en el que aparecen.
>Los bloques de instancia se ejecutan luego de
la llamada a super() en el constructor.

class Init {
Init(int x) {
System.out.println("1-arg const");
}
Init() {
System.out.println("no-arg const");
}
static { System.out.println("1st static init");}
{ System.out.println("1st instance init"); }
{ System.out.println("2nd instance init"); }
static { System.out.println("2nd static init"); }
public static void main(String [] args) {
new Init();
new Init(7);
}
}

?
static int [] x = new int[4];
static { x[4] = 5; }

>Funciona?

? ?

Wrappers
>En Java existe un wrapper por cada tipo
primitivo (Float de float, Integer de int, etc).
>Todos los wrappers tienen dos constructores
(excepto Character): uno que toma un
primitivo del tipo que envuelve y uno que
toma una representacin de tipo String del
tipo a construir.
Integer i1 = new Integer(42);
Integer i2 = new Integer("42");

Wrappers (II)
>La clase Character provee un nico
constructor, que toma un char como
argumento.
Character c1 = new Character('c');

Conversin de Wrappers a primitivos


>Cuando necesitamos convertir el valor de
wrappers a primitivos, podemos usar alguno
de los mtodos ____Value() de esa clase.
Integer i2 = new Integer(42);
byte b = i2.byteValue();
short s = i2.shortValue();
double d = i2.doubleValue();

parse____() y valueOf()
>Ambos toman un String como argumento y
arrojan una excepcin
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

toString()
>La idea de este mtodo es obtener una
representacin coherente de un objeto dado.
>Todos los wrappers poseen un mtodo
toString esttico sobrecargado que toma un
primitivo del tipo apropiado.

AutoBoxing
>En Java 5 aparece
esta caracterstica
conocida como
autoboxingautounboxing o
simplemente boxingunboxing.
>int pInt = 420;
>Integer wInt = pInt; // autoboxing
>int p2 = wInt; // auto-unboxing

>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

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);

Boxing, ==, equals()


>Por ahora, sabemos que la intencin de
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");

Boxing, ==, equals() (II)


>Dos instancias de Boolean, Byte, Character
(de \u0000 a \u007f), Short e Integer (-128 a
127) sern == 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");

Sobrecarga
>Veamos 3 cosas que pueden hacer la
sobrecarga un poco engaosa.
>Widening
>AutoBoxing
>Var-args

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 mtodo con el
argumento que cumple con ser el menor de los ms
amplios que el parmetro.

}}//

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); // Cul de los go() se invoca?
}
}

>El compilador, Decide hacer widening o


autoboxing?

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); // Cul de los go() se invoca?
}
}

Conclusin
>El orden en que el compilador elige es el
siguiente:
1. Mismo tipo
2. Widening
3. Boxing
4. Var-args

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) { }
}

>El compilador ensancha la referencia de


Dog3 a Animal, y la invocacin funciona
correctamente. La clave es que el widening
de referencias depende de la herencia.

Sobrecarga combinando widening y


boxing

>La regla es que el compilador puede ajustar


una invocacin siempre y cuando slo
requiera una nica conversin.

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
}}

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?

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
}
}

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));
} }

>Cul es el resultado?
A. 1 1 B. 2 1 C. 3 3 D. 4 3

Resumen
>El widening de primitivos usa el tipo ms
pequeo posible.
>Boxing y Var-args, usados individualmente,
son compatibles con sobrecarga.
>No se puede ensanchar de un wrapper a otro.
>Widening -> Boxing = falla
>Boxing -> Widening = funciona
>Puede combinarse Var-args con widening o
boxing.

Garbage Collection
>En C, C++ y otros lenguajes, el programador
es responsable de la administracin de
memoria.
>En Java, se provee un hilo de sistema que se
encarga de esta tarea.

Garbage Collection (II)


>Durante los ciclos ociosos de la JVM, el
garbage collector revisa y libera la memoria
que este en condiciones de ser liberada.
>Elegible significa que puede ser
recolectado.
>Solo podemos pedir el garbage collector
usando System.gc();
>No puede forzarse, sino ms bien, sugerirse.

Garbage Collection (III)


>En el examen tendremos que identificar
cuales objetos son elegibles para ser
recolectados.
>La clave es encontrar los objetos que refieren
a NULL.

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. Excepcin

Preguntas

Potrebbero piacerti anche