Un programa és, en essència, dades que es transformen. Les variables són els recipients on deses aquestes dades i els tipus són les regles que determinen què cap en cada recipient i quines operacions hi tenen sentit. En Java aquestes regles es comproven abans d'executar res, i això converteix el sistema de tipus en la teva primera xarxa de seguretat: molt del que en altres llenguatges peta en producció, aquí ni tan sols compila. En aquesta lliçó aprendràs els vuit tipus primitius, la diferència crucial entre primitius i referències, el comportament especial de String, les conversions de tipus, les constants i la inferència amb var. En acabar hauràs modelat amb variables el primer llibre del catàleg de BiblioTech.

Contingut

  1. Declaració, inicialització i assignació
  2. Els vuit tipus primitius
  3. Literals: com s'escriuen els valors
  4. Primitius davant de referències: què desa cada variable
  5. String: el tipus especial
  6. Conversions de tipus
  7. Embolcalls, autoboxing i conversió des de text
  8. final i constants
  9. Inferència de tipus amb var
  10. Modelant un llibre de BiblioTech
  11. Errors Habituals i Consells
  12. Exercicis

  1. Declaració, inicialització i assignació

Tres operacions que convé distingir des del principi:

int anyPublicacio;                // 1. DECLARACIO: reservem el nom i fixem el tipus
anyPublicacio = 2018;             // 2. ASSIGNACIO: li donem un valor
int diesRetard = 12;              // 3. DECLARACIO + INICIALITZACIO en una sola linia
  • Declarar és anunciar al compilador: "existirà una variable anomenada anyPublicacio que contindrà enters". A partir d'aquí, el compilador vigila que no hi fiquis cap altra cosa.
  • Inicialitzar és donar-li el seu primer valor.
  • Assignar és donar-li un valor (el primer o qualsevol altre de posterior). El símbol = no significa igualtat matemàtica, sinó "desa el de la dreta a la variable de l'esquerra".

Una regla que Java imposa i que convé celebrar: no pots llegir una variable local abans d'assignar-li un valor.

int diesRetard;
System.out.println(diesRetard);   // ERROR de compilacio: variable diesRetard might not have been initialized

Altres llenguatges et retornarien brossa o undefined; Java es nega a compilar. Això elimina tota una família d'errors subtils.

Pots declarar diverses variables del mateix tipus en una línia, encara que per llegibilitat es prefereix una per línia:

int diesPrestec = 15, diesRetard = 12;   // valid, pero poc llegible

  1. Els vuit tipus primitius

Java té exactament vuit tipus primitius. No són objectes: són valors purs que la JVM manipula de manera directa i eficient.

Tipus Categoria Mida Rang Valor per defecte Ús típic
byte Enter 8 bits −128 a 127 0 Dades binàries, estalvi de memòria
short Enter 16 bits −32.768 a 32.767 0 Poc utilitzat
int Enter 32 bits −2.147.483.648 a 2.147.483.647 0 L'enter per defecte
long Enter 64 bits ±9,22 × 10¹⁸ 0L Marques de temps, identificadors, xifres grans
float Decimal 32 bits ~7 dígits significatius 0.0f Poc utilitzat; precisió insuficient
double Decimal 64 bits ~15 dígits significatius 0.0d El decimal per defecte
char Caràcter 16 bits 0 a 65.535 (un caràcter Unicode) ' ' Un únic caràcter
boolean Lògic Depèn de la JVM true o false false Condicions, banderes

Notes importants sobre aquesta taula:

  • La columna "valor per defecte" només s'aplica als camps d'una classe (mòdul 3), no a les variables locals dins de main, que com acabem de veure s'han d'inicialitzar explícitament.
  • A la pràctica faràs servir int, double, boolean i char el 95 % del temps. byte, short i float són casos especials.
  • long és imprescindible quan int es queda curt. El límit d'int (uns 2.147 milions) sembla enorme fins que comptes mil·lisegons: el nombre de mil·lisegons des del 1970 va desbordar int el 1970 + 24 dies.
  • char no és un String d'un caràcter: s'escriu amb cometes simples ('A') i és un tipus numèric per sota.
  • boolean en Java no és un número. No existeix l'equivalència "0 és fals, 1 és cert" de C: if (1) no compila.
byte codiSeccio = 3;                        // seccions de la biblioteca: 1..12
short exemplarsTotals = 850;                // llibres al cataleg de Nexus Software
int anyPublicacio = 2018;
long identificadorPrestec = 100000000045L;  // la L es obligatoria: no cap en un int
float pesLlibreKg = 0.68f;                  // la f es obligatoria
double multa = 3.75;
char inicialSeccio = 'J';                   // cometes SIMPLES
boolean disponible = true;

  1. Literals: com s'escriuen els valors

Un literal és un valor escrit directament al codi. Java admet diverses notacions:

Literals enters

int decimal = 2018;              // base 10, el normal
int hexadecimal = 0x7E2;         // base 16, prefix 0x  -> 2018
int binari = 0b11111100010;      // base 2, prefix 0b   -> 2018 (des de Java 7)
int octal = 03742;               // base 8, prefix 0    -> 2018 (evitar: confon)

long codiLlarg = 9788498750102L;     // sufix L obligatori si supera el rang d'int

Compte amb l'octal: int x = 010; val 8, no pas 10. És una font clàssica d'errors; evita els zeros a l'esquerra.

Guions baixos com a separadors

Des de Java 7 pots fer servir _ per fer llegibles els números llargs. El compilador els ignora completament:

int pressupostAnual = 1_250_000;         // es llegeix molt millor que 1250000
long isbnNumeric = 978_000_000_0001L;
int mascara = 0b1010_0101_1100_0011;

Restriccions: no poden anar al principi, al final, ni al costat del punt decimal.

Literals decimals

double multa = 3.75;
double tarifa = 0.25d;           // la d es opcional: double es el tipus per defecte
float pes = 0.68f;               // la f SI que es obligatoria
double notacioCientifica = 1.5e3;    // 1500.0

Regla que causa molts errors: un literal decimal sense sufix és double. Per això float pes = 0.68; no compila: estàs intentant ficar un double dins d'un float, que és més petit. Cal escriure 0.68f.

Literals de caràcter i booleans

char lletra = 'J';
char codi = 74;              // char es numeric per sota: 74 es la 'J' en Unicode
char salt = '\n';            // sequencia d'escapada

boolean disponible = true;
boolean prestat = false;

Seqüències d'escapada més utilitzades:

Seqüència Significat
\n Salt de línia
\t Tabulador
\" Cometa doble dins d'un String
\' Cometa simple dins d'un char
\\ Barra invertida

  1. Primitius davant de referències: què desa cada variable

Aquesta és una de les idees més importants del mòdul, i la que explica molts comportaments que d'una altra manera semblen arbitraris.

Java divideix els tipus en dues famílies:

  • Tipus primitius (els vuit anteriors): la variable conté el valor directament.
  • Tipus per referència (String, arrays, i totes les classes): la variable conté una referència (una adreça) a un objecte que viu en una altra zona de memòria.

La memòria d'un programa Java s'organitza, de manera simplificada, en dues zones:

  • La pila (stack): ràpida i petita, desa les variables locals dels mètodes.
  • El monticle (heap): gran, desa els objectes. És on actua el recol·lector de brossa.
flowchart LR
    subgraph Pila["Pila (variables locals de main)"]
        A["anyPublicacio<br/><b>2018</b>"]
        B["disponible<br/><b>true</b>"]
        C["titol<br/><b>ref → #a1b2</b>"]
        D["autor<br/><b>ref → #c3d4</b>"]
    end
    subgraph Heap["Monticle (objectes)"]
        E["#a1b2<br/>String: 'Java Eficac'"]
        F["#c3d4<br/>String: 'Joshua Bloch'"]
    end
    C --> E
    D --> F

Fixa't en la diferència: anyPublicacio és 2018; titol no és el text, sinó una fletxa que hi apunta.

Conseqüències pràctiques immediates:

// Amb primitius: es copia el VALOR
int diesA = 12;
int diesB = diesA;    // diesB rep una copia del numero
diesA = 20;
System.out.println(diesB);   // 12 -> diesB no s'ha vist afectada

// Amb referencies: es copia la REFERENCIA
String titolA = "Java Eficac";
String titolB = titolA;       // totes dues apunten al MATEIX objecte

Una variable de referència pot valer, a més, null, que significa "no apunta a cap objecte". Els primitius no poden ser mai null.

String editorial = null;   // valid: la referencia no apunta a res
// int pagines = null;     // ERROR: un int sempre te un numero

Intentar fer servir una referència null produeix l'error d'execució més famós de Java, NullPointerException. El tractaràs formalment al mòdul 6.

  1. String: el tipus especial

String no és un primitiu, és una classe. Però rep un tracte tan privilegiat del llenguatge que es comporta a mig camí.

Creació

String titol = "Java Eficac";                     // forma normal, amb literal
String autor = new String("Joshua Bloch");        // funciona, pero NO es fa servir

String és l'única classe que es pot crear amb un literal, sense new. Fer servir new String(...) és un antipatró: crea un objecte extra sense cap avantatge.

Immutabilitat

Un String no es pot modificar mai. Tots els mètodes que "canvien" una cadena retornen en realitat una cadena nova:

String titol = "Java Eficac";
titol.toUpperCase();                   // calcula "JAVA EFICAC"... i el llenca
System.out.println(titol);             // continua imprimint "Java Eficac"

titol = titol.toUpperCase();           // CORRECTE: desem el resultat
System.out.println(titol);             // "JAVA EFICAC"

Aquest és un dels errors més freqüents de qui comença. Si un mètode de String no sembla fer res, gairebé segur que has oblidat desar-ne el resultat.

Per què són immutables? Per seguretat (una cadena no pot canviar sota els teus peus), per eficiència (permet compartir cadenes idèntiques al pool de cadenes) i perquè les fa segures entre fils sense cap cost (mòdul 8).

Concatenació

String titol = "Java Eficac";
int anyPublicacio = 2018;

String fitxa = titol + " (" + anyPublicacio + ")";
System.out.println(fitxa);   // Java Eficac (2018)

L'operador + concatena. Quan un dels operands és un String, Java converteix automàticament l'altre a text. Això també significa que "Total: " + 2 + 3 produeix "Total: 23" i no "Total: 5": s'avalua d'esquerra a dreta, i tan bon punt hi ha un String tota la resta s'hi enganxa com a text. Es corregeix amb parèntesis: "Total: " + (2 + 3).

Mètodes essencials

Partim de:

String titol = "  Java Eficac  ";
Mètode Què fa Exemple Resultat
length() Nombre de caràcters "Java Eficac".length() 11
trim() Elimina espais dels extrems titol.trim() "Java Eficac"
strip() Com trim però Unicode-aware (Java 11+) titol.strip() "Java Eficac"
toUpperCase() Tot a majúscules "java".toUpperCase() "JAVA"
toLowerCase() Tot a minúscules "JAVA".toLowerCase() "java"
substring(i) Des de l'índex i fins al final "Java Eficac".substring(5) "Eficac"
substring(i, j) De l'índex i al j (sense incloure j) "Java Eficac".substring(0, 4) "Java"
equals(altre) Contingut idèntic? "java".equals("Java") false
equalsIgnoreCase(altre) Idèntic ignorant majúscules "java".equalsIgnoreCase("Java") true
isEmpty() Longitud zero? "".isEmpty() true
isBlank() Buida o només espais? (Java 11+) " ".isBlank() true
contains(txt) Conté aquest fragment? "Java Eficac".contains("Efi") true
replace(a, b) Substitueix "Java".replace('a', 'o') "Jovo"
charAt(i) Caràcter a la posició i "Java".charAt(0) 'J'
indexOf(txt) Posició de la primera aparició (−1 si no hi és) "Java Eficac".indexOf("E") 5

Els índexs comencen en 0, i substring(i, j) inclou i però exclou j. És la convenció de tot Java; interioritza-la ja.

Exemple aplicat a BiblioTech:

String isbn = "978-0000000001";

System.out.println("ISBN complet:   " + isbn);
System.out.println("Prefix GS1:     " + isbn.substring(0, 3));    // "978"
System.out.println("Codi:           " + isbn.substring(4));       // "0000000001"
System.out.println("Longitud:       " + isbn.length());           // 14

Text blocks (Java 15+)

Per a textos de diverses línies existeix una sintaxi amb triple cometa que evita els \n i les concatenacions:

String capcalera = """
        ============================================
          BiblioTech - Nexus Software
          Sistema de gestio de la biblioteca
        ============================================
        """;

System.out.println(capcalera);

Detalls: la triple cometa d'obertura ha d'anar seguida d'un salt de línia, i el sagnat es calcula respecte a la línia de tancament, de manera que pots sagnar el bloc dins del codi sense que aquells espais apareguin a la sortida. És enormement còmode per a menús, plantilles o fragments de JSON i SQL.

  1. Conversions de tipus

Quan barreges tipus numèrics, Java aplica regles estrictes.

Conversió eixamplant (widening): automàtica

Va d'un tipus petit a un de més gran. No es perd informació, així que Java la fa sola:

byte → short → int → long → float → double
        char ↗
int diesRetard = 12;
double diesComDecimal = diesRetard;     // automatic: 12.0
System.out.println(diesComDecimal);     // 12.0

Això explica per què 12 * 0.25 dona 3.0: l'int es converteix a double abans de multiplicar.

Conversió estrenyent (narrowing): requereix cast explícit

Va d'un tipus gran a un de més petit. Pot perdre informació, així que Java t'obliga a demanar-la explícitament amb un cast, que és la teva signatura de "sé el que faig":

double multaExacta = 3.75;
int multaEntera = (int) multaExacta;    // cast obligatori
System.out.println(multaEntera);        // 3  <- es TRUNCA, no s'arrodoneix

Punts crítics:

  • El cast a enter trunca, no arrodoneix. (int) 3.99 és 3. Per arrodonir es fa servir Math.round(3.99), que dona 4.
  • Si el valor no hi cap, el resultat és brossa silenciosa:
int gran = 200;
byte petit = (byte) gran;
System.out.println(petit);   // -56  <- desbordament silencios

Aquí no hi ha error ni avís: el compilador assumeix que sabies què feies. Per això els casts s'han de fer servir amb coneixement de causa.

Promoció en expressions

En una operació entre tipus diferents, Java promociona al més gran dels dos:

int diesRetard = 12;
double tarifa = 0.25;
double multa = diesRetard * tarifa;     // int es promociona a double -> 3.0

I el parany clàssic, que veurem a fons a la lliçó d'operadors:

int total = 5;
int parts = 2;
double resultat = total / parts;        // 2.0, NO 2.5

La divisió es fa entre enters (donant 2) i només després es converteix a double. La solució és forçar-ho abans: (double) total / parts.

  1. Embolcalls, autoboxing i conversió des de text

Cada primitiu té una classe embolcall (wrapper) que el representa com a objecte:

Primitiu Embolcall
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Per a què serveixen? Per dos motius:

  1. Les col·leccions (mòdul 5) només admeten objectes, no primitius. No pots tenir una llista d'int, però sí d'Integer.
  2. Poden ser null, cosa que permet representar "sense valor" (un any de publicació desconegut, per exemple).

Autoboxing i unboxing

Des de Java 5, la conversió entre primitiu i embolcall és automàtica:

Integer anyObjecte = 2018;      // autoboxing: int -> Integer
int anyPrimitiu = anyObjecte;   // unboxing: Integer -> int

És còmode, però té dos costos que convé conèixer: consumeix més memòria i, sobretot, un unboxing sobre una referència null llança NullPointerException. Regla pràctica: fes servir primitius llevat que necessitis null o una col·lecció.

Mètodes estàtics útils dels embolcalls

Aquí hi ha la seva utilitat més immediata en aquest mòdul: convertir text a número. Recorda que els arguments de línia d'ordres i el que es llegeix per consola arriben sempre com a String.

String textAny = "2018";
int anyPublicacio = Integer.parseInt(textAny);          // 2018 com a numero

String textMulta = "3.75";
double multa = Double.parseDouble(textMulta);           // 3.75 com a numero

// Constants utils
System.out.println(Integer.MAX_VALUE);   // 2147483647
System.out.println(Integer.MIN_VALUE);   // -2147483648

// Conversio inversa: numero -> text
String comText = String.valueOf(2018);

Si el text no representa un número vàlid (Integer.parseInt("dos mil")), el programa falla en execució amb NumberFormatException. Com capturar i tractar aquesta fallada s'estudia al mòdul 6; de moment n'hi ha prou amb saber que existeix i amb introduir dades correctes.

  1. final i constants

La paraula final aplicada a una variable significa que el seu valor no pot canviar després d'assignar-se:

final double TARIFA_DIARIA = 0.25;
TARIFA_DIARIA = 0.30;   // ERROR de compilacio: cannot assign a value to final variable

Per què fer-les servir:

  • Comuniquen intenció. Qui llegeix el codi sap que aquell valor és una regla de negoci, no una dada variable.
  • Eviten errors. Un valor que no ha de canviar, no pot canviar per accident.
  • Eliminen els "números màgics". Comparar un 0.25 escampat per vint llocs amb una única TARIFA_DIARIA és la diferència entre poder canviar la tarifa en un minut o en una tarda.

Les constants s'escriuen en MAJUSCULES_AMB_GUIO_BAIX, com vam veure a la lliçó anterior:

final double TARIFA_DIARIA = 0.25;      // euros per dia de retard
final int DIES_PRESTEC = 15;            // durada estandard del prestec
final double MULTA_MAXIMA = 20.0;       // sostre de multa per prestec
final String NOM_EMPRESA = "Nexus Software";

Un matís important per a més endavant: en una variable de referència, final impedeix reassignar la referència, no modificar l'objecte apuntat. Amb String no es nota perquè són immutables, però amb objectes mutables (mòdul 3) sí.

  1. Inferència de tipus amb var

Des de Java 10 pots ometre el tipus d'una variable local i deixar que el compilador el dedueixi del valor assignat:

var titol = "Java Eficac";           // el compilador infereix String
var anyPublicacio = 2018;            // infereix int
var multa = 3.75;                    // infereix double
var disponible = true;               // infereix boolean

És crucial entendre que var no converteix Java en un llenguatge de tipatge dinàmic. El tipus es fixa en compilació i és tan estricte com sempre:

var titol = "Java Eficac";
titol = 2018;    // ERROR: titol es String per sempre

Quan sí i quan no

Situació Recomanació Exemple
El tipus és evident pel valor Fes servir var var scanner = new Scanner(System.in);
El tipus és llarg i repetitiu Fes servir var var cataleg = new HashMap<String, Llibre>();
El tipus no es dedueix llegint Evita var var resultat = processar(dades);
Vols un tipus concret diferent de l'inferit No facis servir var double tarifa = 1; (amb var seria int)
Literals numèrics simples Discutible; el tipus explícit sol ser més clar int diesRetard = 12;

Restriccions de var:

  • Només per a variables locals (dins de mètodes). No val per a camps de classe ni paràmetres.
  • Obliga a inicialitzar a la mateixa línia: var x; no compila.
  • No admet null com a valor inicial: var x = null; no compila, perquè no hi ha tipus a inferir.

Aquest curs fa servir tipus explícits al mòdul 1 (perquè vegis sempre quin tipus hi ha en joc) i var a partir del mòdul 5, on els tipus genèrics el fan realment útil.

  1. Modelant un llibre de BiblioTech

Apliquem tot el que hem après. El catàleg de Nexus Software necessita registrar, per a cada llibre: títol, autor, ISBN, any de publicació i disponibilitat. Amb el que saps avui, això es tradueix en variables soltes:

public class CatalegBiblioTech {

    public static void main(String[] args) {

        // --- Constants de negoci de BiblioTech ---
        final String NOM_EMPRESA = "Nexus Software";
        final double TARIFA_DIARIA = 0.25;      // euros per dia de retard
        final int DIES_PRESTEC = 15;            // durada estandard del prestec

        // --- Dades del primer llibre del cataleg ---
        String titol = "Java Eficac";
        String autor = "Joshua Bloch";
        String isbn = "978-0000000001";
        int anyPublicacio = 2018;
        boolean disponible = true;

        // --- Dades d'un prestec en curs ---
        String empleat = "Marta Ruiz";
        int diesTranscorreguts = 27;
        int diesRetard = diesTranscorreguts - DIES_PRESTEC;    // 12
        double multa = diesRetard * TARIFA_DIARIA;             // int * double -> double

        // --- Sortida ---
        System.out.println("=== " + NOM_EMPRESA + " - BiblioTech ===");
        System.out.println();
        System.out.println("Titol:       " + titol);
        System.out.println("Autor:       " + autor);
        System.out.println("ISBN:        " + isbn);
        System.out.println("Publicacio:  " + anyPublicacio);
        System.out.println("Disponible:  " + disponible);
        System.out.println();
        System.out.println("Prestat a:   " + empleat);
        System.out.println("Dies de retard: " + diesRetard);
        System.out.println("Multa acumulada: " + multa + " EUR");
    }
}

Sortida:

=== Nexus Software - BiblioTech ===

Titol:       Java Eficac
Autor:       Joshua Bloch
ISBN:        978-0000000001
Publicacio:  2018
Disponible:  true

Prestat a:   Marta Ruiz
Dies de retard: 12
Multa acumulada: 3.0 EUR

La limitació que ja es nota

Aquest enfocament funciona per a un llibre. Però Nexus Software en té centenars. Amb variables soltes necessitaries titol1, titol2, titol3… i res no garantiria que autor2 correspon realment a titol2. Les dades que formen una unitat conceptual estan escampades.

Aquesta és exactament la mancança que resol la programació orientada a objectes: al mòdul 3 crearàs una classe Llibre que agrupi aquestes cinc variables en un únic tipus, i al mòdul 5 desaràs centenars d'aquests objectes en una col·lecció. Fixa't que els noms que estàs fent servir ara (titol, autor, isbn, anyPublicacio, disponible) seran literalment els camps d'aquella classe. N'estàs posant la base.

Errors Habituals i Consells

  • Oblidar desar el resultat d'un mètode de String. titol.toUpperCase(); no canvia res. Ha de ser titol = titol.toUpperCase();.
  • float x = 3.75; no compila. Els literals decimals són double; cal escriure 3.75f.
  • long x = 10000000000; no compila. El literal s'interpreta com a int i desborda. Cal escriure 10000000000L.
  • Confondre 'A' amb "A". Cometes simples és char, dobles és String. No són intercanviables.
  • Esperar que (int) 3.99 sigui 4. El cast trunca. Per arrodonir, Math.round().
  • Fer servir == per comparar String. Compara referències, no contingut. Es fa servir equals(). És tan important que la lliçó següent hi dedica un apartat sencer.
  • Declarar variables sense inicialitzar i llegir-les. El compilador ho impedeix en variables locals; agraeix-ho.
  • Abusar de var. var resultat = calcular(); obliga el lector a anar a buscar la signatura del mètode. Fes-lo servir només quan el tipus sigui evident.
  • Consell: declara final tot allò que no hagi de canviar. És gratis i converteix un error potencial en un error de compilació.
  • Consell: fes servir noms que diguin què conté la variable, no de quin tipus és. diesRetard és millor que numeroEnter1.
  • Consell: quan dubtis d'un mètode de String, obre'l a JShell i prova'l. Cinc segons davant de deu minuts de suposicions.

Exercicis

Exercici 1: Predir la sortida

Sense executar el codi, escriu què imprimeix cada línia i justifica per què. Després comprova-ho a JShell o compilant-lo.

public class ProvaTipus {
    public static void main(String[] args) {
        int a = 7;
        int b = 2;
        System.out.println(a / b);
        System.out.println((double) a / b);
        System.out.println((int) 3.99);
        System.out.println(Math.round(3.99));

        String titol = "Java Eficac";
        titol.toUpperCase();
        System.out.println(titol);
        System.out.println(titol.substring(0, 4));
        System.out.println(titol.length());

        System.out.println("Total: " + 2 + 3);
        System.out.println("Total: " + (2 + 3));

        byte petit = (byte) 300;
        System.out.println(petit);
    }
}

Exercici 2: Fitxa completa d'un llibre

Escriu la classe FitxaCompleta que declari les variables necessàries per al llibre "Patrons de Disseny" (ISBN 978-0000000002, any 1994, autor "Erich Gamma i altres", disponible) i calculi i mostri:

  1. Els anys d'antiguitat del llibre respecte al 2026.
  2. L'ISBN sense el prefix 978-.
  3. El títol en majúscules.
  4. Si el títol té més de 10 caràcters (fes servir una variable boolean i calcula'n el valor amb una comparació, sense if).

Fes servir constants final on correspongui i respecta les convencions de nomenclatura.

Exercici 3: Corregir els errors de tipus

El codi següent té sis errors de compilació relacionats amb tipus. Troba'ls, explica cadascun i escriu-ne la versió corregida.

public class ErrorsTipus {
    public static void main(String[] args) {
        float tarifaDiaria = 0.25;
        long identificador = 100000000045;
        char seccio = "J";
        int multa = 3.75;
        final int DIES_PRESTEC = 15;
        DIES_PRESTEC = 20;
        int pagines;
        System.out.println(pagines);
    }
}

Solucions

Solució 1

3
3.5
3
4
Java Eficac
Java
11
Total: 23
Total: 5
44

Justificació línia a línia:

  • a / b3. Tots dos són int, així que es fa divisió entera: el resultat 3,5 es trunca a 3. És l'error més clàssic de Java.
  • (double) a / b3.5. El cast s'aplica a a abans de dividir, així que l'operació és 7.0 / 2 i per promoció dona 3.5.
  • (int) 3.993. El cast a enter trunca la part decimal; no arrodoneix.
  • Math.round(3.99)4. Aquest sí que arrodoneix a l'enter més proper.
  • titolJava Eficac. toUpperCase() retorna una cadena nova que es descarta, perquè no s'ha assignat. Els String són immutables.
  • substring(0, 4)Java. Des de l'índex 0 inclòs fins al 4 exclòs: caràcters 0, 1, 2 i 3.
  • length()11. "Java Eficac" té 4 + 1 espai + 6 = 11 caràcters.
  • "Total: " + 2 + 3Total: 23. S'avalua d'esquerra a dreta: "Total: " + 2 dona "Total: 2", i a aquella cadena s'hi enganxa el 3.
  • "Total: " + (2 + 3)Total: 5. Els parèntesis forcen la suma numèrica primer.
  • (byte) 30044. Un byte només arriba a 127. El valor desborda i es conserven únicament els 8 bits baixos de 300 (10010110000101100 = 44). No hi ha cap avís: és una pèrdua silenciosa.

Solució 2

public class FitxaCompleta {

    public static void main(String[] args) {

        // Constants: valors que no canvien durant l'execucio
        final String NOM_EMPRESA = "Nexus Software";
        final int ANY_ACTUAL = 2026;
        final int LONGITUD_TITOL_LLARG = 10;
        final String PREFIX_ISBN = "978-";

        // Dades del llibre
        String titol = "Patrons de Disseny";
        String autor = "Erich Gamma i altres";
        String isbn = "978-0000000002";
        int anyPublicacio = 1994;
        boolean disponible = true;

        // 1. Antiguitat: resta d'enters
        int antiguitat = ANY_ACTUAL - anyPublicacio;

        // 2. ISBN sense prefix. PREFIX_ISBN.length() val 4, aixi que
        //    substring(4) retorna tot a partir del cinque caracter.
        String isbnSensePrefix = isbn.substring(PREFIX_ISBN.length());

        // 3. Titol en majuscules. Desem el resultat: els String son immutables.
        String titolMajuscules = titol.toUpperCase();

        // 4. Una comparacio produeix directament un boolean, sense necessitat d'if.
        boolean titolLlarg = titol.length() > LONGITUD_TITOL_LLARG;

        // --- Sortida ---
        System.out.println("=== " + NOM_EMPRESA + " - BiblioTech ===");
        System.out.println("Titol:             " + titol);
        System.out.println("Autor:             " + autor);
        System.out.println("ISBN:              " + isbn);
        System.out.println("Publicacio:        " + anyPublicacio);
        System.out.println("Disponible:        " + disponible);
        System.out.println("Antiguitat:        " + antiguitat + " anys");
        System.out.println("ISBN sense prefix: " + isbnSensePrefix);
        System.out.println("Titol majuscules:  " + titolMajuscules);
        System.out.println("Titol llarg:       " + titolLlarg);
    }
}

Sortida:

=== Nexus Software - BiblioTech ===
Titol:             Patrons de Disseny
Autor:             Erich Gamma i altres
ISBN:              978-0000000002
Publicacio:        1994
Disponible:        true
Antiguitat:        32 anys
ISBN sense prefix: 0000000002
Titol majuscules:  PATRONS DE DISSENY
Titol llarg:       true

La idea clau del punt 4: una comparació com ara titol.length() > 10 és una expressió booleana. No cal cap if per obtenir true o false; l'if serveix per decidir què fer amb aquest valor, i això arriba al mòdul 2.

Solució 3

Els sis errors:

  1. float tarifaDiaria = 0.25; — el literal 0.25 és double; no cap en un float sense sufix. Solució: 0.25f (o millor, fer servir double).
  2. long identificador = 100000000045; — el literal s'interpreta com a int i en desborda el rang. Falta el sufix L.
  3. char seccio = "J"; — les cometes dobles creen un String. Un char necessita cometes simples: 'J'.
  4. int multa = 3.75; — assignar un double a un int és una conversió estrenyent i requereix cast explícit (o, millor, declarar multa com a double, que és el correcte per a diners).
  5. DIES_PRESTEC = 20; — la variable és final; no es pot reassignar.
  6. System.out.println(pagines);pagines s'ha declarat però no s'ha inicialitzat mai, i les variables locals han de tenir valor abans de llegir-se.

Versió corregida:

public class ErrorsTipus {
    public static void main(String[] args) {
        double tarifaDiaria = 0.25;             // 1. double es el tipus natural per a decimals
        long identificador = 100000000045L;     // 2. sufix L per a literals long
        char seccio = 'J';                      // 3. cometes simples per a char
        double multa = 3.75;                    // 4. l'import es decimal, no enter
        final int DIES_PRESTEC = 15;            // 5. constant: s'assigna una sola vegada
        int pagines = 416;                      // 6. inicialitzada abans de fer-se servir

        System.out.println("Tarifa diaria:  " + tarifaDiaria);
        System.out.println("Identificador:  " + identificador);
        System.out.println("Seccio:         " + seccio);
        System.out.println("Multa:          " + multa);
        System.out.println("Dies prestec:   " + DIES_PRESTEC);
        System.out.println("Pagines:        " + pagines);
    }
}

Conclusió

Ja saps declarar, inicialitzar i assignar variables; coneixes els vuit tipus primitius amb els seus rangs i quins faràs servir de debò; escrius literals en qualsevol base i amb sufixos correctes; distingeixes els primitius (que desen el valor) de les referències (que desen una fletxa al monticle); domines String, la seva immutabilitat i els seus mètodes essencials, inclosos els text blocks; converteixes entre tipus entenent quan la conversió és automàtica i quan trunca; fas servir embolcalls i Integer.parseInt per transformar text en número; protegeixes les teves regles de negoci amb final; i saps quan var ajuda i quan fa nosa. Amb tot això has modelat el primer llibre de BiblioTech.

A la lliçó següent, Operadors, posarem aquestes dades en moviment: aritmètica (inclòs el parany de la divisió entera i el mòdul), assignació composta, increment i decrement, comparacions, operadors lògics amb avaluació de curtcircuit, l'operador ternari, operacions a nivell de bit, precedència, i l'error clàssic de comparar cadenes amb == en comptes d'equals. El fil conductor serà el càlcul de la multa per retard d'un préstec de BiblioTech.

Curs de Programació en Java

Mòdul 1: Introducció a Java

Mòdul 2: Flux de control

Mòdul 3: Programació orientada a objectes

Mòdul 4: Programació orientada a objectes avançada

Mòdul 5: Estructures de dades i col·leccions

Mòdul 6: Gestió d'excepcions

Mòdul 7: Entrada/sortida de fitxers

Mòdul 8: Multifil i concurrència

Mòdul 9: Xarxes

Mòdul 10: Temes avançats

Mòdul 11: Frameworks i llibreries de Java

Mòdul 12: Construcció d'aplicacions del món real

© Copyright 2026. Tots els drets reservats