PDA

View Full Version : [Java] Variabili "globali"


Pompolus
06-02-2008, 20:40
Salve a tutti,

volevo sapere come si fa in Java a definire delle variabili in modo da poterle usare in tutte le classi di uno stesso package.

Ho provato a dichiararle public o protected in una classe ma le altre classi non le vedono.


Altra domanda:

Se ho una classe A che istanzia una classe B, può creare problemi se nella definizione di B metto che estende A?

Grazie

afsdfdlecosdfsfdcco
06-02-2008, 20:46
Salve a tutti,

volevo sapere come si fa in Java a definire delle variabili in modo da poterle usare in tutte le classi di uno stesso package.

Ho provato a dichiararle public o protected in una classe ma le altre classi non le vedono.

In java non esistono "variabili globali". La cosa piu' simile che puoi fare è creare una classe di sole variabili "public static" e poi fai un import static nelle altre classi (si, è contorto)

wingman87
06-02-2008, 20:48
Per la prima domanda, parli di variabili d'istanza o statiche?
protected dovrebbe essere il modificatore corretto, ma forse per quello che devi fare tu devi aggiungere anche static. Dipende da cosa vuoi fare, non si è capito bene.
http://java.sun.com/docs/books/tutorial/java/javaOO/accesscontrol.html

Per la seconda domanda non sono sicuro ma credo di no

AnonimoVeneziano
06-02-2008, 20:49
Altra domanda:

Se ho una classe A che istanzia una classe B, può creare problemi se nella definizione di B metto che estende A?

Grazie

Non ho mai provato, ma ad occhio direi di si.

E poi non avrebbe molto senso logicamente (se B è una estensione di A com'è che A necessita di B per eseguire il suo lavoro? Significherebbe che la stessa B avrebbe bisogno di se stessa per poter fare quello per cui è stata progettata)

Ciao

wingman87
06-02-2008, 20:56
E poi non avrebbe molto senso logicamente (se B è una estensione di A com'è che A necessita di B per eseguire il suo lavoro? Significherebbe che la stessa B avrebbe bisogno di se stessa per poter fare quello per cui è stata progettata)
Non ho capito, è troppo contorto :D

Ad ogni modo, al di là del senso logico le istanze di A e B sono comunque delle entità distinte, quindi perché A non dovrebbe poter istanziare B?

fek
06-02-2008, 21:09
volevo sapere come si fa in Java a definire delle variabili in modo da poterle usare in tutte le classi di uno stesso package.


Si fa' cosi':

Pompolus
06-02-2008, 21:12
In java non esistono "variabili globali". La cosa piu' simile che puoi fare è creare una classe di sole variabili "public static" e poi fai un import static nelle altre classi (si, è contorto)

Ho provato ma non sembra funzionare,
che io sappia poi in Java una classe importa di default tutte le altre classi dello stesso package...

Comuqnue ho definito come static ste variabili ma nelle altre classi non le riconosce.

Qualche altro consiglio? :(

wingman87
06-02-2008, 21:17
Posta il codice così vediamo

PS: usa il tag CODE

Pompolus
06-02-2008, 21:37
Allora, cerco di spiegare un pò meglio:

premetto che questo è il mio primo programma in Java quindi perdonatemi se dico o ho fatto qualche sfondone.

Io devo realizzare un sistema client/server dove il server può gestire più connessioni assegnando a ognuna di esse un thread dedicato.

Il problema nasce proprio però quando la classe CollabServer chiama il costruttore di CollabHandler(che è la classe che dovrebbe far partire il thread per gestire la connessione). Quando ciò avviene si verifica una IOException e CollabHandler non parte.

Notate che CollabServer estende thread mentre CollabHandler estende CollabServer proprio per poter usufruire di alcune variabili in comune.

Ecco il codice delle 2 classi:

CollaServer


package serverclientprova;

import java.net.*;
import java.io.*;
import java.util.*;

public class CollabServer extends Thread {
//--------------------------------------------------
protected FilmInProg [] vFiP;
protected String info = "";
protected MessageInputStream mis;
protected MessageOutputStream mos;
protected BufferedReader bis;
protected BufferedWriter bos;
protected int nM;

public CollabServer() throws IOException {
MemorizzaFile();
nM = ContaMatrici();
vFiP = new FilmInProg [nM];
CreaVettore();
ServerSocket server = new ServerSocket(1414);

System.out.println ("Accepting connections...");
while(true) {
Socket client = server.accept(); //ogni richiesta di connessione viene accettata
System.out.println ("Accepted from " + client.getInetAddress());
try{
new CollabHandler(client).start(); /////QUI E' IL PROBLEMA////////
}catch(IOException e){
System.out.println("IO Exception" + "\n");
}//Istanziamo un oggetto CollabHandler per gestire la connessione }
}
}


public void MemorizzaFile () throws IOException {
try{
bis = new BufferedReader(new InputStreamReader(new FileInputStream("DbCinema.txt"))); //apriamo il file di testo contenente le info
String temp = "";
while( (temp = bis.readLine()) != null)
info = info + temp + "\n";
} catch(IOException e){
System.out.println("IO Exception" + "\n");
}
finally {
try {
bis.close();
} catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
}
}


public int ContaMatrici () throws IOException { //conta il numero delle matrici che dovranno esser create
String inputLine = "";
int num = 0;
try {
bis = new BufferedReader(new InputStreamReader(new FileInputStream("DbCinema.txt"))); //apriamo il file di testo contenente le info
inputLine = bis.readLine();
while (inputLine.compareTo("FINE") != 0) {
bis.readLine();
inputLine = bis.readLine();
while (inputLine.compareTo("---") != 0) {
num++;
inputLine = bis.readLine();
}
inputLine = bis.readLine();
}
}
catch (IOException e) {
System.out.println("IO Exception" + "\n");
} finally {
try {
bis.close();
} catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
}
return num;
}

public void CreaVettore () throws IOException {
String NomeF, NomeS, t;
int i = 0;
try{
bis = new BufferedReader(new InputStreamReader(new FileInputStream("DbCinema.txt")));
NomeF = bis.readLine();
while (NomeF.compareTo("FINE") != 0){
NomeS = bis.readLine();
t = bis.readLine();
while (t.compareTo("---") != 0){
vFiP[i] = new FilmInProg( NomeF, NomeS, t);
i++;
t = bis.readLine();
}
NomeF = bis.readLine();
}
}catch (IOException e) {
System.out.println("IO Exception" + "\n");
}finally{
try {
bis.close();
} catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
}
}

//--------------------------------------------------
public static void main(String args[]) throws IOException {
new CollabServer();

}
}



CollabHandler


package serverclientprova;

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;



public class CollabHandler extends CollabServer {
protected Socket socket;
// protected MessageInputStream mis;
// protected MessageOutputStream mos;
protected ObjectInputStream ois;
protected ObjectOutputStream oos;


//--------------------------------------------------
public CollabHandler(Socket socket) throws IOException {
this.socket = socket;
try{
mis = new MessageInputStream(socket.getInputStream());
mos = new MessageOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
}catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
}



public void run () {

try{
while(true){
System.out.println("QUI CI ARRIVA");
mis.receive();
try{
Thread.sleep(1000);
}catch (InterruptedException ex) {}
String cmd = mis.readUTF();
if (cmd.equals ("Richiedi"))
Richiedi();
else if (cmd.equals ("PostiLiberi")){
mis.receive();
String Sala = mis.readUTF();
String Orario = mis.readUTF();
PostiLiberi(Sala, Orario);
}
else if (cmd.equals ("Compra"))
Compra();
}
}
catch (ClassNotFoundException ex) {
Logger.getLogger(CollabHandler.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex){
ex.printStackTrace();
}
}
.
.
.
.

andbin
06-02-2008, 21:42
volevo sapere come si fa in Java a definire delle variabili in modo da poterle usare in tutte le classi di uno stesso package.Premesso che una cosa del genere non è una gran bellezza e bisognerebbe capire meglio perché hai bisogno di fare questo e come intendi usarle.

Se proprio vuoi renderle visibili solamente a classi nello stesso package (e vale anche per la classe che le contiene), allora devono avere livello di accesso di "default" (package level), cioè non va specificato un modificatore di accesso. Poi le metti static. Quindi:

class Globali
{
static int a;
static String b;
}

Pompolus
06-02-2008, 21:49
Premesso che una cosa del genere non è una gran bellezza e bisognerebbe capire meglio perché hai bisogno di fare questo e come intendi usarle.

Se proprio vuoi renderle visibili solamente a classi nello stesso package (e vale anche per la classe che le contiene), allora devono avere livello di accesso di "default" (package level), cioè non va specificato un modificatore di accesso. Poi le metti static. Quindi:

class Globali
{
static int a;
static String b;
}


ho provato a fare come dici tu ma non riesco a far funzionare.
Io ho creato all'interno del package una classe chiamata "Globali" e il codice da te scritto.
Ma nelle altre classi dello stesso package, nè a nè b vengono riconosciute.
Devo fare qualche import o roba del genere?
Ah io uso NetBean, non so se può essere utile ^^

fek
06-02-2008, 21:54
Il prossimo che consiglia ad un principiante di imparare prima il C gli linko questo topic.

AnonimoVeneziano
06-02-2008, 21:54
Scusa, ma CollabHandler estende CollabServer.

Questo significa che CollabHandler è CollabServer.

Che bisogno hai di creare una CollabServer e poi da dentro chiamare una CollabHandler se la CollabHandler fa già il proprio lavoro e allo stesso tempo anche quello della CollabServer (essendo essa stessa una CollabServer visto che la estende) ?.

Usa direttamente la CollabHandler

Ciao

Pompolus
06-02-2008, 21:55
comunque il mio problema resta che la chiamata "new CollabHandler(client).start();" non funziona.

L'unica cosa che ho pensato da cui possa dipendere è il fatto che estende CollabServer e CollabServer estende Thread e che quindi possa dare una qualche sorta di conflitto.

Per questo ho pensato di usare delle variabili "globali" e quindi poter evitare di far estendere CollabServer, ma non sono neanche sicuro che possa essere una soluzione.

Non so proprio perchè non parte : \

Pompolus
06-02-2008, 21:59
Scusa, ma CollabHandler estende CollabServer.

Questo significa che CollabHandler è CollabServer.

Che bisogno hai di creare una CollabServer e poi da dentro chiamare una CollabHandler se la CollabHandler fa già il proprio lavoro e allo stesso tempo anche quello della CollabServer (essendo essa stessa una CollabServer visto che la estende) ?.

Usa direttamente la CollabHandler

Ciao


Allora ripeto questo è il mio primo programma quindi sto andando un pò a casaccio...

Io devo creare un thread per ogni connessione che il server accetta, per questo istanzio un collabhandler per ogni connessione. Solo che collabhandler utilizzerà delle variabili contenute in collabserver ed è SOLO per questo motivo che collabhandler estende collabserver.

Lo so che non è elegante ma è l'unico modo che sono riuscito a trovare per far vedere quelle cazzo di variabili ad entrambe le classi senza doverle passare in tutti i metodi (improponibile).

fek
06-02-2008, 22:01
Lo so che non è elegante ma è l'unico modo che sono riuscito a trovare per far vedere quelle cazzo di variabili ad entrambe le classi senza doverle passare in tutti i metodi (improponibile).

Perche' improponibile? :)
Prova, vedrai che finisci prima che tentando di costringere Java a fare quello che non vuole fare (le variabili globali).

AnonimoVeneziano
06-02-2008, 22:27
Allora ripeto questo è il mio primo programma quindi sto andando un pò a casaccio...

Io devo creare un thread per ogni connessione che il server accetta, per questo istanzio un collabhandler per ogni connessione. Solo che collabhandler utilizzerà delle variabili contenute in collabserver ed è SOLO per questo motivo che collabhandler estende collabserver.

Lo so che non è elegante ma è l'unico modo che sono riuscito a trovare per far vedere quelle cazzo di variabili ad entrambe le classi senza doverle passare in tutti i metodi (improponibile).

Putroppo hai sbagliato il progetto delle due classi.

Devi pensare ad oggetti. Che cos'è (che oggetto è) la CollabServer? Immagino sia l'idealizzazione di un "Server". La CollabHandler cos'è? E' l'idealizzazione di un thread che gestisce la connessione immagino.

Bene.

Quello che hai fatto tu è questo: "La CollabServer è un Server che estende un Thread, mentre la CollabHandler è un gestore di connessione che estende un Server che estende un Thread.

1° - Che bisogno ha il Server di essere un Thread. Perchè hai fatto CollabServer extends Thread? Non ce n'è bisogno, visto che il server non deve essere un thread, ma solo un server. Invece ad essere un Thread dovrebbe essere CollabHandler.

2° - Perchè CollabHandler è un Server? Che bisogno ha CollabHandler di essere un server? Nessuno.

Quindi in sostanza inizia a rifare il progetto partendo da questo suggerimento :

class CollabServer {
// Codice qua
}

e

class CollabHandler extends Thread {
// Codice qua
}

Ciao

Pompolus
06-02-2008, 22:40
Ok, ho eliminato il problema delle variabili globali (Ora CollabServer le passa a CollabHandler), inoltre CollabHandler ora estende Thread (non esetende più CollabServer) e CollabServer non estende più nulla...

Però continua a non funzionare.

Posto il codice di CollabHandler dove si blocca:

package serverclientprova;

import java.net.*;
import java.io.*;
import java.util.*;
// import prominence.msg.*; ?????
import java.util.logging.Level;
import java.util.logging.Logger;



public class CollabHandler extends Thread {
protected Socket socket;
protected MessageInputStream mis;
protected MessageOutputStream mos;
protected ObjectInputStream ois;
protected ObjectOutputStream oos;
protected int nM;
protected String info;
protected FilmInProg [] vFiP;

//--------------------------------------------------
public CollabHandler(Socket socket, String info, int nM, FilmInProg [] vFiP) throws IOException {
this.socket = socket;
this.info = info;
this.nM = nM;
this.vFiP = vFiP.clone();
try{
mis = new MessageInputStream(socket.getInputStream());
mos = new MessageOutputStream(socket.getOutputStream());
}catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
try{

ois = new ObjectInputStream(socket.getInputStream());//Qui è il problema, questa istruzione non viene eseguita e si blocca, perchè?
oos = new ObjectOutputStream(socket.getOutputStream());
}catch (IOException e) {
System.out.println("IO Exception" + "\n");
}
start();
}
.
.
.
.


Quindi CollabServer crea un'istanza di CollabHandler, ma non arrivando all'istruzione "start()" il thread non parte e CollabHandler non fa nulla... Il problema quasi sicuramente deriva dall'uso dell' ObjectInputStream, ma in cosa ho sbagliato??

Grazie ancora dell'aiuto

Pompolus
06-02-2008, 23:19
già finiti i consigli? :(

Pompolus
07-02-2008, 00:28
Raga mi sta venendo un dubbio atroce...

Io devo passare un vettore di oggetti da client a server e viceversa.

Ho usato un ObjectInputStream e un ObjectOutputStream ma mi danno un casino di errori.

Qualcuno può postarmi il codice funzionante?

Ecco come ho fatto io:

Lato server:
ois = new ObjectInputStream(socket.getInputStream());

oos = new ObjectOutputStream(socket.getOutputStream());


Lato Client:

Ois = new ObjectInputStream (i);

Oos = new ObjectOutputStream (o);


dove i e o sono rispettivamenti l'InputStream e l'OutputStream del socket.


Vi prego aiutatemi che sto in alto mare :(:mc: :cry:

banryu79
07-02-2008, 08:23
Potresti cominciare postando l'output della consolle Java quando lanci l'applicazione.

Le eccezioni partono in fase di compilazione o compila tutto e hai errori a runtime?
Posta l'output della consolle e sarà più semplice capire cosa c'è che non va.

afsdfdlecosdfsfdcco
07-02-2008, 13:10
ho provato a fare come dici tu ma non riesco a far funzionare.
Io ho creato all'interno del package una classe chiamata "Globali" e il codice da te scritto.
Ma nelle altre classi dello stesso package, nè a nè b vengono riconosciute.
Devo fare qualche import o roba del genere?

hai fatto un import static delle variabili?

Pompolus
07-02-2008, 14:28
allora il problema è appurato che lo danno l'objectinputstream e l'objectoutputstream.

questa è la classe che dovrebbe gestire la singola connessione

collabhandler:


package serverclientprova;

import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
// import prominence.msg.*; ?????
import java.util.logging.Level;
import java.util.logging.Logger;



public class CollabHandler extends Thread {
protected Socket socket;
protected ObjectInputStream ois;
protected ObjectOutputStream oos;
protected CollabServer S;

//--------------------------------------------------
public CollabHandler(Socket socket, CollabServer CS) throws IOException {
S = CS;
this.socket = socket;
try{
System.out.println("qui arriva 1");
ois = new ObjectInputStream(socket.getInputStream());
System.out.println("qui non arriva 2");
oos = new ObjectOutputStream(socket.getOutputStream());
}catch (IOException e) {
System.out.println("QuestaIO Exception" + "\n");
}
start();
}

.
.
...


Questa è la classe che idealizza il server

CollabServer:


package serverclientprova;

import java.net.*;
import java.io.*;
import java.util.*;

public class CollabServer {
//--------------------------------------------------
protected static FilmInProg [] vFiP;
protected String info = "";
protected BufferedReader bis;
protected BufferedWriter bos;
protected int nM;


public CollabServer() throws IOException {
MemorizzaFile();
nM = ContaMatrici();
vFiP = new FilmInProg [nM];
CreaVettore();
ServerSocket server = new ServerSocket(1414);

System.out.println ("Accepting connections...");
while(true) {
Socket client = server.accept(); //ogni richiesta di connessione viene accettata
System.out.println ("Accepted from " + client.getInetAddress());
try{
new CollabHandler(client, this);
}catch(IOException e){
System.out.println("IO Exception" + "\n");
}//Istanziamo un oggetto CollabHandler per gestire la connessione }
}
}
.
.
...


lo stesso errore lo da anche in ServizioCinema (il client):


package clientserverprova;


import java.io.*;
import java.awt.*;
import java.net.*;
//import prominence.msg.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ServizioCinema extends Frame {
protected static int id = 0;
Label LMsgServer, LInfoFilm, LSala, LOrario, LPostiLiberi;
TextArea TAInfoFilm, TAMsgServer;
TextField TFSala, TFOrario, TFPostiLiberi;
Button BRichiedi, BPostiLiberi, BCompra, BReset;
ObjectInputStream Ois;
ObjectOutputStream Oos;
Button [][] Mb;
String S, O;
short [][] D;
Color g, r, b;


public ServizioCinema (InputStream i, OutputStream o) throws IOException {
super ("Servizio Cinema " + (id ++));
this.setLayout(null); //che fa????
setResizable(false);
try {
System.out.println("qui arriva 1");
Ois = new ObjectInputStream (i);
System.out.println("qui non arriva 1");
Oos = new ObjectOutputStream (o);

}catch (IOException e){
System.out.println("oh 4");
System.out.println("IOException E" + "\n");
}

g = Color.GREEN;
r = Color.RED;
b = Color.BLUE;
.
.
...


Netbean compila tutto tranquillamente, ma in esecuzione si blocca su quelle istruzioni in grassetto.

ecco l'output del server:


init:
deps-jar:
Compiling 1 source file to D:\Download\PROGRAMMAZIONE D RETE\Primo Progetto\ServerclientPROVA 1.1\build\classes
compile:
run:
Accepting connections...
Accepted from /127.0.0.1
qui arriva 1


e quello del client:


init:
deps-jar:
Compiling 1 source file to D:\Download\PROGRAMMAZIONE D RETE\Primo Progetto\CLIENTSERVERPROVA 1.1\build\classes
Note: D:\Download\PROGRAMMAZIONE D RETE\Primo Progetto\CLIENTSERVERPROVA 1.1\src\clientserverprova\ServizioCinema.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
compile:
run:
qui arriva 2


l'errore "Note: D:\Download\PROGRAMMAZIONE D RETE\Primo Progetto\CLIENTSERVERPROVA 1.1\src\clientserverprova\ServizioCinema.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details." credo sia perchè uso alcuni metodi deprecati per creare il frame.


Qualcuno mi sa dire perchè in runtime si bloccano entrambi su sti objectStream??? Li ho dichiarati in qualche modo sbagliato? Ho sbagliato aprendere l'inputstream e l'outputstream? Dio mi vuole male?

Non so dove mettere le mani : \

Pompolus
07-02-2008, 14:30
hai fatto un import static delle variabili?

No ma ho risolto passando un'istanza di CollabServer a CollabHandler, non ho più il problema di come passare le variabili, ma resta il problema sul perchè si blocca su ObjectInputStream e su ObjectOutputStream :cry:

U-Boat
07-02-2008, 15:09
allora il problema è appurato che lo danno l'objectinputstream e l'objectoutputstream.
Qualcuno mi sa dire perchè in runtime si bloccano entrambi su sti objectStream??? Li ho dichiarati in qualche modo sbagliato? Ho sbagliato aprendere l'inputstream e l'outputstream?

Non so dove mettere le mani : \

Ti consiglio di mettere le mani sulla JavaDoc.
Ecco la risposta: http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectInputStream.html#ObjectInputStream(java.io.InputStream)

This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.

AnonimoVeneziano
07-02-2008, 15:18
Non so cosa devi mandare sulla rete, ma dubito tu debba serializzare e trasferire un oggetto ed in genere se è quello che vuoi fare ci sono modi migliori prima di arrivare alla Serializzazione che è l'ultima spiaggia.

Usa una BufferedInputStream e una BufferedOutputStream . Se devi trasferire stringhe attaccaci un Reader e un Writer .

Ciao

Pompolus
07-02-2008, 15:22
Ti consiglio di mettere le mani sulla JavaDoc.
Ecco la risposta: http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectInputStream.html#ObjectInputStream(java.io.InputStream)

This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.

mmm non ho capito però come risolvere :O

Pompolus
07-02-2008, 15:55
Ti consiglio di mettere le mani sulla JavaDoc.
Ecco la risposta: http://java.sun.com/j2se/1.4.2/docs/api/java/io/ObjectInputStream.html#ObjectInputStream(java.io.InputStream)

This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.

come lo flusho sto header?
Io usando una WriteInt subito dopo la creazione dell'objectOutputStream sono riuscito a sbloccarla, ma la ObjectInputStream rimane bloccata, ho rpovato a mettere un readInt ma resta bloccata.

Che faccio?:muro:

Pompolus
07-02-2008, 16:04
come lo flusho sto header?
Io usando una WriteInt subito dopo la creazione dell'objectOutputStream sono riuscito a sbloccarla, ma la ObjectInputStream rimane bloccata, ho rpovato a mettere un readInt ma resta bloccata.

Che faccio?:muro:

Ok ho flushato con il metodo FLush() ovviamente :doh:

grazie mille a tutti