PDA

View Full Version : [java] reference


raniero
05-03-2006, 14:23
Ciao,
vorrei implementare un metodo che mi ritorna un boolean, che mi indica se un oggetto non è stato ancora refererenziato, come potrei fare?
grazie

^TiGeRShArK^
05-03-2006, 15:50
non sono sicuro di aver capito...cmq ci provo:

public boolean isNull(Object o) {
return o == null;
}

ma non sono sciuro se è quello ke avevi chiesto.. :fagiano:

pisto
05-03-2006, 16:29
un oggetto (o meglio un reference, cioè una cosa che punta all'oggetto in sè) non referenziato è
Object x;

con x in questo stato non ci puoi fare proprio niente, il compilatore di darà sempre e comunque errore.
un reference così
Object x=null;
è un reference che sì punta a qualcosa, a null.

raniero
06-03-2006, 01:37
mi spiego meglio:
Invece di chiedermi se object x==null, mi chiedevo se era possibile implementare un metodo che mi faccia la stessa cosa ma senza usare "==null" .

:)

71104
06-03-2006, 13:05
possiamo sapere a cosa ti serve? per realizzare il codice scritto da TigerShark "== null" va usato per forza, poco ma sicuro...

Angus
06-03-2006, 13:24
public boolean ciStaDentro(Object o) {
try {
o.hashCode();
return true;
} catch (NullPointerException ex) {
return false;
}
}


:sofico:

pisto
06-03-2006, 13:27
public boolean ciStaDentro(Object o) {
try {
o.hashCode();
return true;
} catch (NullPointerException ex) {
return false;
}
}


:sofico:
:D

sottovento
06-03-2006, 13:45
La tua richiesta mi ha acceso un dubbio:per caso vuoi realizzare un reference count o qualcosa del genere?
Tutto sommato e' piuttosto semplice controllare se il tuo oggetto e' uguale a null, per cui ho l'impressione che la tua richiesta sia qualcosa di diverso. Sbaglio?

High Flying
Sottovento

raniero
06-03-2006, 14:51
sono un programmatore alle prime armi,siccome mi e' stato contestato in un progetto il fatto di controllare se un "oggetto è == null" e' proprio quello che voglio,penso il tuo metodo vada bene, probabilmente io voglio il contrario:

public boolean isEmpty(Object o) {
try {
o.hashCode();
return false;
} catch (NullPointerException ex) {
return true;
}
}


Grazie per la vostra disponibilità, è un piacere imparare da gente esperta come voi

sottovento
06-03-2006, 15:14
Se ti va, potresti pubblicare il pezzo di codice contestato.
Scusa il mio intervento, ma mi sembra strano che ti obiettino di verificare se stai lavorando con dei dati corretti. Generalmente contestano il fatto che questi controlli non ci siano.....

Magari il tuo codice e' particolare. Se vuoi, per scrupolo, possiamo darci un'occhiata....

High Flying
Sottovento

raniero
06-03-2006, 15:39
certo, ecco qua il codice contestato, il puto critico e' rappresentato dal
"while (mret==null)"..



package com.officina;

import java.util.ArrayList;

public class Officina {
private ArrayList operai;
private ParcoMacchine macchineRiparate;
private CassettaAttrezzi cassettaAttrezzi;
private ArrayList macchineDaRiparare;

public Officina(CassettaAttrezzi cassettaAttrezzi, ParcoMacchine macchineRiparate){
this.cassettaAttrezzi = cassettaAttrezzi;
this.operai = new ArrayList();
this.macchineDaRiparare = new ArrayList();
this.macchineRiparate = macchineRiparate;
}

public void avviaLavori(){
for(int i = 0; i < operai.size(); i++){
if (operai.get(i) instanceof Operaio) {
Operaio operaio = (Operaio) operai.get(i);
operaio.start();
}
}
}

public CassettaAttrezzi prendiCassettaAttrezzi(){
return cassettaAttrezzi;
}

public void aggiungiMeccanico(Operaio operaio){
operai.add(operaio);
}

public synchronized void riponiMacchinaRiparata(Macchina macchina){
macchineRiparate.aggiungiMacchina(macchina);
}

public synchronized void parcheggiaMacchinaDaRiparare(Macchina macchina) throws InterruptedException {
macchineDaRiparare.add(macchina);
notifyAll();
}

public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {
Macchina mRet = null;
Object objTmp = null;

while(mRet == null){ // punto critico!!!!!!!!!!!!!!
if (macchineDaRiparare.size() != 0){
objTmp = macchineDaRiparare.remove(0);
if (objTmp instanceof Macchina) {
mRet = (Macchina) objTmp;
}
} else wait();
}
return mRet;
}
}







grazie 1000 sottovento.. mi piacerebbe imparare molto da gente come te..

sottovento
06-03-2006, 15:53
Ciao,
grazie per gli immeritati complimenti, ma non credo di poter insegnare niente.

Ho controllato il codice che hai postato, e mi sembra in ordine (purtroppo nella pubblicazione si e' persa l'indentazione originale, immagino. Comunque e' comprensibile).

Da quello che ho capito, questa funzione ritorna la prima macchina disponibile alla riparazione. Nel caso non ci siano, si addormenta ed aspetta che ne arrivino. Come effetto collaterale, svuota la pila che contiene la lista delle macchine da riparare e, forse, altre cose...

Beh, se e' questo quanto ti era richiesto di fare, direi che allora ci siamo. Se non era questo, puo' darsi che io abbia capito male o analizzato male il codice.
Ad ogni modo non vedo grossi problemi.

La curiosita' aumenta: ti hanno contestato il fatto che usi un confronto a null? per quale motivo?

Piccola domanda: spesso nelle aziende che usano Java, hanno del personale che proviene dal C e ogni tanto "mischiano" i linguaggi, visto che sono tanto simili. E' il caso di chi ha mosso la contestazione?

High Flying
Sottovento

Angus
06-03-2006, 16:05
certo, ecco qua il codice contestato, il puto critico e' rappresentato dal
"while (mret==null)"..



package com.officina;

import java.util.ArrayList;


...


public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {
Macchina mRet = null;
Object objTmp = null;

while(mRet == null){ // punto critico!!!!!!!!!!!!!!
if (macchineDaRiparare.size() != 0){
objTmp = macchineDaRiparare.remove(0);
if (objTmp instanceof Macchina) {
mRet = (Macchina) objTmp;
}
} else wait();
}
return mRet;
}
}


Mi astengo dallo stravolgere il codice. Però potresti pensare se questo fa al caso tuo:


public synchronized Macchina prendiMacchinaDaRiparare() {

while(macchineDaRiparare.size() == 0) { // punto critico!!!!!!!!!!!!!! }

return (Macchina) macchineDaRiparare.remove(0);

}

crick_pitomba
06-03-2006, 16:21
public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {
Macchina mRet = null;
Object objTmp = null;

while(mRet == null){ // punto critico!!!!!!!!!!!!!!
if (macchineDaRiparare.size() != 0){
objTmp = macchineDaRiparare.remove(0);
if (objTmp instanceof Macchina) {
mRet = (Macchina) objTmp;
}
} else wait();
}
return mRet;
}
}
[/CODE]


Scusa, ma non capisco una cosa: a me quel while sembra completamente inutile
il ciclo non viene comunque eseguito una sola volta?

raniero
06-03-2006, 16:27
esatto, finche non ci sono macchine da riparare continua a cercare nella lista macchine, quando la trova ritorna la macchina da riparare.. il motivo della contestazione non lo so, ho solo il punto di codice segnato in rosso dal mio prof!(sono uno studente).. dici che posso utilizzare la funzione che mi hai suggerito ( al contrario) per modificare il codice e fare sparire il null?

:muro:

raniero
06-03-2006, 16:45
ah ecco forse ci sono, devo utilizzare un "while (true)" e mi risolvo tutti i problemi...


public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {


while(true){
if (macchineDaRiparare.size() != 0){
return (Macchina) macchineDaRiparare.remove(0);
}
else wait();
}
}

sottovento
06-03-2006, 17:03
ah ecco forse ci sono, devo utilizzare un "while (true)" e mi risolvo tutti i problemi...


public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {


while(true){
if (macchineDaRiparare.size() != 0){
return (Macchina) macchineDaRiparare.remove(0);
}
else wait();
}
}



Questo codice e' sensibilmente diverseo dal precedente, poiche' qui supponi che nell'oggetto macchineDaRiparare ci sia sempre un oggetto di tipo macchina. La supposizione veniva a mancare nella versione precedente.

Ho un nuovo indizio, ora: hai un professore, e non un direttore tecnico, a cui rispondere.
In tal caso, i programmi sono di dimensioni piu' corte ma vengono controllati in maniera piu' approfondita.
E' quindi probabile che quel punto di domanda sia stato messo perche' il codice, anche se e' corretto, contiene delle parti inutili (diciamo evitabili) come, appunto, quel controllo.
Si puo' in effetti riscrivere l'algoritmo (vedo che l'hai gia' fatto) e renderlo piu' snello. Forse era questo che il prof. intendeva.

Piu' semplicemente, invece che un ciclo infinito, potresti scrivere:

while (macchineDaRiparare.size() != 0)
{
// ...
}

(detto fra noi: generalmente io scrivo
while (macchineDaRiparare.size() > 0)
perche' la condizione piu' forte e' sempre la piu' sicura, ed e' una buona abitudine da prendere. Ovviamente stai facendo un esame, quindi devi entrare nella testa di chi ti sta davanti, prima ancora che pensare a queste cose. Magari non gli piace e ti riempie di segni rossi....)

High Flying
Sottovento

crick_pitomba
06-03-2006, 17:10
Ecco...

Prima durante il primo ciclo di while arrivava al return e indipendentemente dal valore presente (null oppure diverso da null) restituiva il valore (ovviamente per questo motivo il ciclo veniva eseguito un'unica volta).

adesso invece aspetta che effettivamente ottieni un oggetto e quindi restituisce un valore valido.

Ma a questo punto potresti tagliare la testa al toro con


public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {


while(macchineDaRiparare.size() == 0)){
wait();
}
return (Macchina) macchineDaRiparare.remove(0);

}


edit: in questo caso assumo che ci siano più metodi che cercano di prelevare la macchina dalla coda

altrimenti il codice potrebbe essere semplicemente



public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {


if (macchineDaRiparare.size() == 0))
wait();
return (Macchina) macchineDaRiparare.remove(0);

}



in questo modo se la lista è vuota il codice viene bloccato fino al primo notify().
Quando viene sbloccato siccome il codice è nella clausola syncrhonized dovresti essere sicuro che c'è qualcosa nella lista.

Angus
06-03-2006, 17:15
Ecco...

Prima durante il primo ciclo di while arrivava al return e indipendentemente dal valore presente (null oppure diverso da null) restituiva il valore (ovviamente per questo motivo il ciclo veniva eseguito un'unica volta).

adesso invece aspetta che effettivamente ottieni un oggetto e quindi restituisce un valore valido.

Ma a questo punto potresti tagliare la testa al toro con


public synchronized Macchina prendiMacchinaDaRiparare() throws InterruptedException {


while(macchineDaRiparare.size() == 0)){
wait();
}
return (Macchina) macchineDaRiparare.remove(0);

}


A questo punto non posso fare a meno di chiedere lo scopo di quel wait()...

edit: alla prima lettura mi era sfuggito il notifyAll().

raniero
06-03-2006, 17:15
grazie 1000 per le dritte.. quindi suppongo che te sei un programmatore professionista, e che hai un direttore tecnico pignolo!

:)

crick_pitomba
06-03-2006, 17:18
A questo punto non posso fare a meno di chiedere lo scopo di quel wait()...

il wait() è necessario perchè il codice ha la clausola syncrhonized

raniero
06-03-2006, 17:21
A questo punto non posso fare a meno di chiedere lo scopo di quel wait()...

se la lista non contiene macchine .... aspetta

Angus
06-03-2006, 17:28
ho visto il notifyAll() e non capisco come possa funzionare, partendo dal presupposto che ad un dato istante 1 operaio è bloccato nella wait() e tutti gli altri sono in coda cercando di entrare nel metodo sincronizzato: chi può chiamare il metodo parcheggiaMacchinaDaRiparare se l'Officina è loccata dal primo operaio?

ma magari il funzionamento è completamente diverso... va bene a domani che sennò perdo il metrò per lo sciopero sindacale... :rolleyes:

il_luridone
06-03-2006, 17:30
Intermezzo tecnico:

Java non permette "dangling references" ovvero riferimenti al niente. Tutte le variabili che dichiari, a runtime vengono inizializzate o al valore specificato esplicitamente o "all'oggetto" null (o a zero, in caso di valori numerici). Quindi in buona sostanza il tuo problema iniziale non ha molto senso così com'è posto.

Per saperne di più (http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.12.5).