Entra

View Full Version : clone[java]


nuovoUtente86
30-07-2007, 18:43
da una guida universitaria:

"Come per equals, il metodo deve avere esattamente la stessa intestazione del metodo di Object:

class Studente {
String nome;
int anno;

Object clone() {
...
}
}

Non funziona nemmeno cosí:

clone() in Studente cannot override
clone() in java.lang.Object;
attempting to assign weaker access
privileges; was protected

A parole: si possono allargare i diritti, ma non restringere

Va dichiarato protected oppure public

"

L' errore nn dovrebbe però comparire dato che in assenza di specificatore d' accesso java assegna protected,per cui la gerarchia sarebbe rispettata.

PGI-Bis
30-07-2007, 20:05
in assenza di specificatore d' accesso java assegna non protected ma "innominato", default, package, ha mille nomi, l'unica certezza è che vale meno di protected, forse perchè limita l'accesso ad un'unità di compilazione che appartenga allo stesso package, mentre protected consente l'accesso tramite un riferimento che sia dello stesso tipo o di un sottotipo di quello che dichiara il membro protetto, anche in un package diverso.

nuovoUtente86
30-07-2007, 20:53
gia è vero ci sono delle differenza tra protected e package.Ma è vero che la visibilità di package nn da accesso alle sottoclassi?Facendo delle prove pratiche riesco ad accedere ad una varibaili metodo package ereditando dalla classe che li definisce.
in pratica nello stesso package:

public class A{
void metodo(){}}

public class B extends B{
void metodo1(){metodo();}}

funziona tutto perfettamente.

andbin
31-07-2007, 08:27
Ma è vero che la visibilità di package nn da accesso alle sottoclassi?Per essere precisi:

default (package) = visibile da altre classi o sottoclassi ma sempre e solo nello stesso package.

protected = visibile da altre classi nello stesso package o da sottoclassi in qualunque package (stesso o diverso).

PGI-Bis
31-07-2007, 11:00
credo che non sia un problema di visibilità ma di accessibilità. Vale a dire c'è ma non si può "toccare". Si vede bene nell'introspezione. I membri di una classe sono tutti quelli visibili a prescindere dal fatto che siano o non siano accessibili (cioè private, "package", protected o public). Una volta "visti", e si vedono tutti, la palla passa al modificatore d'accesso, a meno che non si usi setAccessibile, caso in cui l'accessibilità va a ramengo e restano solo le politiche di sicurezza.

nuovoUtente86
31-07-2007, 11:32
in pratica con getDeclaredFields() e setaccessible() si viola la politica di incapsulamento?Non conosco bene come funzionano i 2 metodi esattamente per cui potrei dire una sciocchezza.

cioè in sostanza in 2 metdo accedono e modificano solo i campi public o tutti i campi?

mad_hhatter
31-07-2007, 11:54
credo che non sia un problema di visibilità ma di accessibilità. Vale a dire c'è ma non si può "toccare". Si vede bene nell'introspezione. I membri di una classe sono tutti quelli visibili a prescindere dal fatto che siano o non siano accessibili (cioè private, "package", protected o public). Una volta "visti", e si vedono tutti, la palla passa al modificatore d'accesso, a meno che non si usi setAccessibile, caso in cui l'accessibilità va a ramengo e restano solo le politiche di sicurezza.

qual è la differenza tra visibilità e accessibilità? ho cercato un po' ma spesso le due cose vengono usate come sinonimo, anche se secondo me è sbagliato... però mi puoi indirizzare sulla definizione rigorosa dei due concetti?

e potresti darmi qualche info sulle politiche di sicurezza? cosa sono e come si settano?

grazie mille

nuovoUtente86
31-07-2007, 12:10
invece personalmente preferisco utilizzarli come sinonimo.Cmq grossolanamente la differenza dovrebbe essere questa..con un esempio:

Field[]field=classe.getDeclaredFields();

ora le sole variabili public sono accessibili quind anche modificabili..mentre le altre sono visibili ma in pratica nn si puo operare su di loro nè in letture ne in scrittura.

Da quello che ho capito facendo
AccessibleObject.setAccessible(field,true);
si dovrebbero rendere tutte le varibili accessibili a meno del gestore della sicurezza.Ecco mi piacerebbe sapere circa questi gestori di sicurezza.

La spiegazìone deriva da una lettura al volo delle specifiche per cui potrebbe essere errata.in tal caso attendo correzioni.

PGI-Bis
31-07-2007, 13:09
Ho messo "credo" per un'entrata soft. In verità visibilità ed accessibilità sono sicuramente fenomeni disgiunti. Esistono cose che sono accessibili ma non visibili (pensiamo ad un membro adombrato o occultato) e cose che sono visibili ma non accessibili (per la presenza di un modificatore restrittivo).

Accessibile non è modificabile ma "riferibile", nel senso di poter far riferimento a. Una classe non è modificabile, a prescindere dal fatto che sia accessibile o meno.

Le politiche di sicurezza. Un'introduzione rapidissima.

Quando scarichi un programma Java da internet non è che prendi e lo lanci col sorriso sulle labbra e le dita incrociate. Applichi le politiche di sicurezza standard e vedi un po' cosa ti dice il sistema. Per farlo basta aggiungere:

-Djava.security.manager

tra le opzioni di esecuzione.

Le restrizioni imposte sono praticamente le stesse di un'Applet non certificata. La cosa interessante è che i tentativi di eseguire operazioni non consentite si traducono in eccezioni sulla console, quindi uno può vedere cosa il programma vorrebbe fare e decidere se farglielo fare.

Le politiche di sicurezza sono specificate in un file di testo che si può generare manualmente o tramite "policytool", un programma allegato al JDK.

Supponiamo che il programma sia questo:

import java.io.*;

public class PolicyTest {

public static void main(String[] args) {
PrintStream out = null;
try {
out = new PrintStream("z:\\policytest\\hello world.txt");
out.println("hello world");
out.flush();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if(out != null) out.close();
}
}
}

Eseguendolo con:

java PolicyTest

il programma scrive il suo file.

Sulla linea di comando digitiamo:

policytool

Premiamo "Aggiungi policy entry" e subito "fine", poi "file -> salva" e salviamo nella cartella del file "PolicyTest.class" come "test.policy"

Ora eseguiamo il programma usando le politiche di sicurezza descritte in "test.policy" che non consentono praticamente niente.

java -Djava.security.manager -Djava.security.policy=test.policy PolicyTest

Sulla console appare un'eccezione di sicurezza:

Exception in thread "main" java.security.AccessControlException: access denied (
java.io.FilePermission z:\policytest\hello world.txt write)

Ci informa che la piattaforma ha negato al programma il permesso di scrivere il file "hello world.txt"

Da linea di comando, digitiamo:

policytool

Poi file -> apri -> test.policy

Selezioniamo "CodeBase <ALL>" e premiamo "Modifica policy entry"

Aggiungi permesso
Permesso: FilePermission
Nome obiettivo: z:\policytest\*
Azioni: write

Premere ok, fine, file->salva

Eseguiamo nuovamente il programma con il comando di prima:

java -Djava.security.manager -Djava.security.policy=test.policy PolicyTest

e notiamo come l'eccezione di sicurezza non si ripete. Il file che specifica le politiche di sicurezza, infatti, consente al programma di scrivere un file in z:\policytest\.

Se tentiamo di scrivere in una cartella diversa da z:\policytest\:

import java.io.*;

public class PolicyTest {

public static void main(String[] args) {
PrintStream out = null;
try {
out = new PrintStream("z:\\hello world.txt");
out.println("hello world");
out.flush();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if(out != null) out.close();
}
}
}

Torniamo punto e a capo:

Z:\policytest>java -Djava.security.manager -java.security.policy=test.policyPolicyTest
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission z:\hello world.txt write)

Tornano al file policy, il "CodeBase" di un "policy entry" è il percorso d'origine del programma: dove si trova. IL nostro codebase è "ALL", cioè "a prescindere da dove si trovi il programma" o "vale per tutti". Ma si può anche dire "tutti i programmi che si trovano in z:\policytest", basta mettere nel codebase:

file:z:/policytest/

Il succo è questo. L'insieme di possibilità e amorevolmente descritto nella documentazione standard, a cui rimando.

nuovoUtente86
31-07-2007, 13:31
Ho messo "credo" per un'entrata soft. In verità visibilità ed accessibilità sono sicuramente fenomeni disgiunti. Esistono cose che sono accessibili ma non visibili (pensiamo ad un membro adombrato o occultato) e cose che sono visibili ma non accessibili (per la presenza di un modificatore restrittivo).

Accessibile non è modificabile ma "riferibile", nel senso di poter far riferimento a. Una classe non è modificabile, a prescindere dal fatto che sia accessibile o meno..

Ipotizziamo:
public class Variabile{
publi void setQualcosa(){}}

public MiaClasse{
public Variabile variabile;}

Miaclasse mc=new MiaClasse();
mc.variabile.setQualcosa();

sfruttando l' accessibilita sono riuscito a modificare l' oggetto senza cambiare alcun riferimento.ProbABILmente nn ho bene inteso il tuo concetto.

cos' è un membro occultato?





Le politiche di sicurezza. Un'introduzione rapidissima.

Quando scarichi un programma Java da internet non è che prendi e lo lanci col sorriso sulle labbra e le dita incrociate. Applichi le politiche di sicurezza standard e vedi un po' cosa ti dice il sistema. Per farlo basta aggiungere:

-Djava.security.manager

tra le opzioni di esecuzione.

Le restrizioni imposte sono praticamente le stesse di un'Applet non certificata. La cosa interessante è che i tentativi di eseguire operazioni non consentite si traducono in eccezioni sulla console, quindi uno può vedere cosa il programma vorrebbe fare e decidere se farglielo fare.

Le politiche di sicurezza sono specificate in un file di testo che si può generare manualmente o tramite "policytool", un programma allegato al JDK.

Supponiamo che il programma sia questo:

import java.io.*;

public class PolicyTest {

public static void main(String[] args) {
PrintStream out = null;
try {
out = new PrintStream("z:\\policytest\\hello world.txt");
out.println("hello world");
out.flush();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if(out != null) out.close();
}
}
}

Eseguendolo con:

java PolicyTest

il programma scrive il suo file.

Sulla linea di comando digitiamo:

policytool

Premiamo "Aggiungi policy entry" e subito "fine", poi "file -> salva" e salviamo nella cartella del file "PolicyTest.class" come "test.policy"

Ora eseguiamo il programma usando le politiche di sicurezza descritte in "test.policy" che non consentono praticamente niente.

java -Djava.security.manager -Djava.security.policy=test.policy PolicyTest

Sulla console appare un'eccezione di sicurezza:

Exception in thread "main" java.security.AccessControlException: access denied (
java.io.FilePermission z:\policytest\hello world.txt write)

Ci informa che la piattaforma ha negato al programma il permesso di scrivere il file "hello world.txt"

Da linea di comando, digitiamo:

policytool

Poi file -> apri -> test.policy

Selezioniamo "CodeBase <ALL>" e premiamo "Modifica policy entry"

Aggiungi permesso
Permesso: FilePermission
Nome obiettivo: z:\policytest\*
Azioni: write

Premere ok, fine, file->salva

Eseguiamo nuovamente il programma con il comando di prima:

java -Djava.security.manager -Djava.security.policy=test.policy PolicyTest

e notiamo come l'eccezione di sicurezza non si ripete. Il file che specifica le politiche di sicurezza, infatti, consente al programma di scrivere un file in z:\policytest\.

Se tentiamo di scrivere in una cartella diversa da z:\policytest\:

import java.io.*;

public class PolicyTest {

public static void main(String[] args) {
PrintStream out = null;
try {
out = new PrintStream("z:\\hello world.txt");
out.println("hello world");
out.flush();
} catch(IOException ex) {
ex.printStackTrace();
} finally {
if(out != null) out.close();
}
}
}

Torniamo punto e a capo:

Z:\policytest>java -Djava.security.manager -java.security.policy=test.policyPolicyTest
Exception in thread "main" java.security.AccessControlException: access denied (java.io.FilePermission z:\hello world.txt write)

Tornano al file policy, il "CodeBase" di un "policy entry" è il percorso d'origine del programma: dove si trova. IL nostro codebase è "ALL", cioè "a prescindere da dove si trovi il programma" o "vale per tutti". Ma si può anche dire "tutti i programmi che si trovano in z:\policytest", basta mettere nel codebase:

file:z:/policytest/

Il succo è questo. L'insieme di possibilità e amorevolmente descritto nella documentazione standard, a cui rimando.Come si aggiungono le politiche?cioè scarico un jar..cosa devo fare?


P.s Cosa ne pensi di quello che ho scitto nel post precedente su setAccessible?

PGI-Bis
31-07-2007, 14:45
L'accesso è quando scrivi:

mc.variabile

accedi al membro "variabile" di mc. Accesso è anche quando scrivi:

mc.new Bingo();

con Bingo classe interna non annidata, vale a dire:

public class MC {
public class Bingo {}
}

Esiste una questione di accesso ovunque si tratti di fare riferimento ad un membro o ad un tipo (classi o interfacce, eventualmente annidate), a prescindere dal fatto che quell'accesso sia funzionale alla modifica di qualcosa.

Pensiamo ad un "getter". Non c'è modifica eppure c'è una questione di accessibilità.

Forse l'accessibilità è una precondizione della modifica ma io punterei più a separare le due questioni.

setAccessible(true) consente di accedere riflessivamente ad un membro altrimenti inaccessibile.

Esempio:

public class PrivateHolder {
private void doSome() {
System.out.println("i'm doing somenthing private here!");
}
}

import java.lang.reflect.*;

public class Main {

public static void main(String[] args) throws Throwable {
Method m = PrivateHolder.class.getDeclaredMethod("doSome");
m.setAccessible(true);
m.invoke(new PrivateHolder());
}
}

La seconda turpitudine ammessa è la mutazione di un campo terminale. Si può modificare il valore del campo FINAL_VALUE?

public class FinalHolder {
public final String FINAL_VALUE = "hello world";
}

Sì, riflessivamente:

import java.lang.reflect.*;

public class Main {

public static void main(String[] args) throws Throwable {
Field f = FinalHolder.class.getDeclaredField("FINAL_VALUE");
FinalHolder instance = new FinalHolder();
System.out.println(f.get(instance));
f.setAccessible(true);
f.set(instance, "va da via 'l cu.");
System.out.println(f.get(instance));
}
}

Questione delicatissima perchè "final" per il compilatore significa "non cambia" e, se non cambia, allora il compilatore tende a sotituire i riferimenti con il valore. Così se FinalHolder avesse un getFinalValue, quel metodo restituirebbe "hello world" a prescindere dalla mutazione riflessiva non perchè quest'ultima non ha avuto successo ma perchè il compilatore ha sostituito nel getter this.FINAL_FIELD con "hello world".

Vale la pena di ricordare come l'uso di setAccessible sia impedibile via politiche di sicurezza.

Come si aggiungono le politiche.

Le politiche sono contenute in un file di testo semplice. Quel file lo crei tu stesso. Per comodità puoi generare quel file con policytool, programma incluso nel JDK. Ad esempio questo è un file di testo generato da quel programma:

/* AUTOMATICALLY GENERATED ON Tue Jul 31 14:04:44 CEST 2007*/
/* DO NOT EDIT */

grant codeBase "file:z:/policytest/" {
permission java.io.FilePermission "z:\\policytest\\*", "write";
};



Per applicare le politiche definite in questo file, cioè per far sì che la piattaforma java esegua un programma con queste restrizioni di sicurezza, è sufficiente passare il percorso del file che hai creato a java quando lanci il tuo programma.

Supponendo che quel file di testo si chiami "mypol.policy" e che si trovi in:

c:\secpol\

lancerai il programma java con:

java -Djava.security.manager -Djava.security.policy=c:\secpol\mypol.policy {il resto, ad es. -jar Programma.jar}

Non ci sono jar da scaricare nè altro da fare se non creare un file di testo e scriverci dentro le restrizioni di sicurezza usando la sintassi dei file policy. Oppure usi policytool (prova a lanciarlo, da linea di comando scrivi "policytool" + invio) ma è solo una comodità.

mad_hhatter
31-07-2007, 14:54
@PGI-Bis

per l'accessibilità siamo d'accordo: ci riferiamo ai vari concetti di "public, protected, private, friendly-access"

ma mi è ancora poco chiaro il concetto di visibilità... voglio dire, se un membro di una classe A è dichiarato private, ad esempio, una classe B che usi un'istanza di A non può accedere a tale membro privato e, quindi, di fatto non lo vede. In questo senso i due etrmini mi sembrano sinonimi... la differenza semmai la vedo quando con visibilità intendiamo lo scope di una variabile

nuovoUtente86
31-07-2007, 15:43
L'accesso è quando scrivi:

mc.variabile

accedi al membro "variabile" di mc. Accesso è anche quando scrivi:

mc.new Bingo();

con Bingo classe interna non annidata, vale a dire:

public class MC {
public class Bingo {}
}

Esiste una questione di accesso ovunque si tratti di fare riferimento ad un membro o ad un tipo (classi o interfacce, eventualmente annidate), a prescindere dal fatto che quell'accesso sia funzionale alla modifica di qualcosa.

Pensiamo ad un "getter". Non c'è modifica eppure c'è una questione di accessibilità.

Forse l'accessibilità è una precondizione della modifica ma io punterei più a separare le due questioni.

setAccessible(true) consente di accedere riflessivamente ad un membro altrimenti inaccessibile.

Esempio:

public class PrivateHolder {
private void doSome() {
System.out.println("i'm doing somenthing private here!");
}
}

import java.lang.reflect.*;

public class Main {

public static void main(String[] args) throws Throwable {
Method m = PrivateHolder.class.getDeclaredMethod("doSome");
m.setAccessible(true);
m.invoke(new PrivateHolder());
}
}

La seconda turpitudine ammessa è la mutazione di un campo terminale. Si può modificare il valore del campo FINAL_VALUE?

public class FinalHolder {
public final String FINAL_VALUE = "hello world";
}

Sì, riflessivamente:

import java.lang.reflect.*;

public class Main {

public static void main(String[] args) throws Throwable {
Field f = FinalHolder.class.getDeclaredField("FINAL_VALUE");
FinalHolder instance = new FinalHolder();
System.out.println(f.get(instance));
f.setAccessible(true);
f.set(instance, "va da via 'l cu.");
System.out.println(f.get(instance));
}
}

Questione delicatissima perchè "final" per il compilatore significa "non cambia" e, se non cambia, allora il compilatore tende a sotituire i riferimenti con il valore. Così se FinalHolder avesse un getFinalValue, quel metodo restituirebbe "hello world" a prescindere dalla mutazione riflessiva non perchè quest'ultima non ha avuto successo ma perchè il compilatore ha sostituito nel getter this.FINAL_FIELD con "hello world".

Vale la pena di ricordare come l'uso di setAccessible sia impedibile via politiche di sicurezza.

Come si aggiungono le politiche.

Le politiche sono contenute in un file di testo semplice. Quel file lo crei tu stesso. Per comodità puoi generare quel file con policytool, programma incluso nel JDK. Ad esempio questo è un file di testo generato da quel programma:

/* AUTOMATICALLY GENERATED ON Tue Jul 31 14:04:44 CEST 2007*/
/* DO NOT EDIT */

grant codeBase "file:z:/policytest/" {
permission java.io.FilePermission "z:\\policytest\\*", "write";
};



Per applicare le politiche definite in questo file, cioè per far sì che la piattaforma java esegua un programma con queste restrizioni di sicurezza, è sufficiente passare il percorso del file che hai creato a java quando lanci il tuo programma.

Supponendo che quel file di testo si chiami "mypol.policy" e che si trovi in:

c:\secpol\

lancerai il programma java con:

java -Djava.security.manager -Djava.security.policy=c:\secpol\mypol.policy {il resto, ad es. -jar Programma.jar}

Non ci sono jar da scaricare nè altro da fare se non creare un file di testo e scriverci dentro le restrizioni di sicurezza usando la sintassi dei file policy. Oppure usi policytool (prova a lanciarlo, da linea di comando scrivi "policytool" + invio) ma è solo una comodità.




Per quanto rigurda il setAccessible consente di fatto di prendere possesso di tutti i campi anche private e final alla fin fine..a meno delle politiche implementate?

Dicevo se lancio un jar con doppio click quali politiche di protezione si instaurano?


quello che mi è ancora poco chiaro è:

io faccio un mio programma per lo sviluppo del quale utilizzo la riflessione(probabilmente è un assurdopoichè conosco a priori le mie classi) e nn la limito.
Ma un programmatore malvagio cosa potrebbe combinare sfruttando la riflessione,ovvero scrive un ' applicazione maligna e distribuisce il jar ma dove lancia il suo attacco ,verso quali classi fa il setAccessible...e il resto delle operazioni.
In senso funzionali quali sono le applicazioni che si prestano alla riflessione?UnA è quello di una programmazione molto generica e riutilizzabile ma poi il resto?

^TiGeRShArK^
31-07-2007, 16:03
Per quanto rigurda il setAccessible consente di fatto di prendere possesso di tutti i campi anche private e final alla fin fine..a meno delle politiche implementate?

Dicevo se lancio un jar con doppio click quali politiche di protezione si instaurano?
quelle di default del sistema.
Ovvero quelle specificate nella directory home di windows nel file .policy (se non erro) e se non è presente vengono usate quelle di default della VM (che variano a seconda del tipo di applicazione.. .stand-alone/applet/web start).
Sempre se non ricordo male ke è da un pò ke non bestemmio col policy tool :asd:

PGI-Bis
31-07-2007, 17:26
Le restrizioni di sicurezza sono applicate solo alle applicazioni che provengono dal web (applet o java web start). Le applicazioni locali hanno il pieno controllo del sistema.

Per modificare questo comportamento:

http://java.sun.com/docs/books/tutorial/security/tour2/step4.html

ma mi è ancora poco chiaro il concetto di visibilità

Visibilità:

int x = 10;
{
int x = 20;
}

Accessibilità:

class Pippo {
Point p = new Point();
}

Non tutto quello che è visibile/invisibile è accessibile/inaccessibile. La visibilità riguarda i nomi (qualsiasi nome). L'accessibilità riguarda tipi, membri e costruttori. Avendo tipi, membri e costruttori un nome, il loro nome è soggetto alle norme della visibilità.

Sono semplicemente cose diverse. Un membro accessibile può non essere visibile (es. per sovrascrittura) e un membro visibile può non essere accessibile (es. introspezione).

Ma un programmatore malvagio

Oddio, non sono un cracker per cui non è che sappia esattamente cosa possa frullare in testa al maligno. Così su due piedi mi viene in mente la possibilità di sostituire indirizzi di connessione, query sql, creare dei proxy, invocare eseguibili nativi... è una semplice questione di collegamento dinamico: io invoco il metodo x di un Pippo che rispetta un certo contratto, se poi è Pippo o Pluto poco importa.

In senso funzionali quali sono le applicazioni che si prestano alla riflessione?

Possono beneficiarne le applicazioni che scrivono o leggono dati persistenti. Se prendi il JSR220, (persistence API), è la standardizzazione di un pratica piuttosto comune, che è quella di dire:

database.store(unBean)

che prima si faceva con motori riflessivi ad hoc e oggi... si farà ancora così perchè il JSR220 ha una configurazione che è più complicata della divina commedia.

Quanto è "facile" trasformare una classe-bean in una query SQL? Be', è poco più di un ciclo su getDeclaredFields. Lo stesso vale per il recupero dei dati.

Poi c'è "newInstance" e URLClassLoader. Plug-In. Lato desktop è una manna. Crei un'interfaccia che rappresenta un generico servizio e prende come argomento di un suo metodo l'applicazione e sei a cavallo. Puoi estenderla in lungo e in largo, da viva e da morta.

La riflessione è poi una manna per ripulire il codice.

Posso ammazzarmi di:

button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) ...

oppure dire:

button.addActionListener(new Callback(this, "buttonActionPerformed"));

dove "Callback" è un semplicissimo trampolino riflessivo: concretizza ActionListener e spara al metodo buttonActionPerformed di "this".

Il tutto ha un costo, non in performance ma in "sicurezza". Java è un linguaggio polimorfo: tutte le espressioni hanno uno o più tipi. Dal canto suo, l'invocazione riflessiva di metodi è tipicamente amorfa: il tipo del riferimento che subirà l'invocazione è irrilevante, basta che possieda un metodo compatibile con la firma riflessiva.

Ad alcuni piace, ad altri no. A me un po' si e un po' no. Più no con sporadiche eccezioni che sì :D.

mad_hhatter
31-07-2007, 17:57
Visibilità:

int x = 10;
{
int x = 20;
}

Accessibilità:

class Pippo {
Point p = new Point();
}

Non tutto quello che è visibile/invisibile è accessibile/inaccessibile. La visibilità riguarda i nomi (qualsiasi nome). L'accessibilità riguarda tipi, membri e costruttori. Avendo tipi, membri e costruttori un nome, il loro nome è soggetto alle norme della visibilità.

Sono semplicemente cose diverse. Un membro accessibile può non essere visibile (es. per sovrascrittura) e un membro visibile può non essere accessibile (es. introspezione).


perfetto, allora avevo capito bene :) grazie mille (è mai possibile che noi informatici riusciamo sempre a rendere complicate le cose più banali????)

nuovoUtente86
31-07-2007, 21:40
Visibilità:

int x = 10;
{
int x = 20;
}

Accessibilità:

class Pippo {
Point p = new Point();
}

Non tutto quello che è visibile/invisibile è accessibile/inaccessibile. La visibilità riguarda i nomi (qualsiasi nome). L'accessibilità riguarda tipi, membri e costruttori. Avendo tipi, membri e costruttori un nome, il loro nome è soggetto alle norme della visibilità.

Sono semplicemente cose diverse. Un membro accessibile può non essere visibile (es. per sovrascrittura) e un membro visibile può non essere accessibile (es. introspezione).




perfettamente d' accordo che prima prima delle regole di accessibilità il nome di tipi,costruttori è soggetto alla visibilità.Aggiungerei che a questo punto anche i metodi dobbiamo annoverarli tra quelli sottosanti alle regole di accessibilità o sbaglio?

Però volendo arrovellarsi sull' argomento e pur vero che ciò che non è visibile solitamente è anche inaccessibile.

metodo(){
try{int x=0;}
System.out.println(x);}

x non è visibile e nn è accessibile di conseguenza.Del resto penso che una cosa nn visibile nn possa mai essere acceduta....magari nn è cosi e sbaglio io.

PGI-Bis
31-07-2007, 22:38
"tipi membri e costruttori" era per dare l'idea. L'elenco completo è nelle specifiche, include i metodi, i package e credo qualcos'altro.

"solitamente" 'ste cose uno cerca anche di evitarle. Perchè, parliamoci chiaro, quante volte capita di dire:

int x = 10;
{ int x = 11; }

L'unico caso frequente è quello dei metodi "setter": di solito il nome del parametro è lo stesso del campo, a mo' di documentazione. Qui c'è una questione di visibilità (adombramento) ma più che la norma ci si ricorda di scrivere "this.value = value".

Lo dico perchè non si pensi che, programmando, uno deva preoccuparsi più di tanto di certe sottigliezze.

In tema di sottigliezze, un caso di accessibilità senza visibilità, peraltro notevole, si ha con la derivazione.

Una sottoclasse può dichiarare un metodo che ha una firma compatibile con quella di un metodo dichiarato nella superclasse. In questo caso il nome del metodo della superclasse è adombrato da quello della sottoclasse. (JLS, 6.3.1) Il metodo della superclasse è comunque invocabile con la notazione super.nome
Non è visibile, ma è accessibile.

nuovoUtente86
31-07-2007, 23:00
"tipi membri e costruttori" era per dare l'idea. L'elenco completo è nelle specifiche, include i metodi, i package e credo qualcos'altro.

"solitamente" 'ste cose uno cerca anche di evitarle. Perchè, parliamoci chiaro, quante volte capita di dire:

int x = 10;
{ int x = 11; }

L'unico caso frequente è quello dei metodi "setter": di solito il nome del parametro è lo stesso del campo, a mo' di documentazione. Qui c'è una questione di visibilità (adombramento) ma più che la norma ci si ricorda di scrivere "this.value = value".

Lo dico perchè non si pensi che, programmando, uno deva preoccuparsi più di tanto di certe sottigliezze.

In tema di sottigliezze, un caso di accessibilità senza visibilità, peraltro notevole, si ha con la derivazione.

Una sottoclasse può dichiarare un metodo che ha una firma compatibile con quella di un metodo dichiarato nella superclasse. In questo caso il nome del metodo della superclasse è adombrato da quello della sottoclasse. (JLS, 6.3.1) Il metodo della superclasse è comunque invocabile con la notazione super.nome
Non è visibile, ma è accessibile.
si ottimo esempio.In realtà suu ho fatto un errore io in quanto considero membri le sole variabili mentrw ala fine anche i metodi sono membri della classe.
(JLS, 6.3.1)?

PGI-Bis
31-07-2007, 23:12
(JLS, 6.3.1)?

Infedele!!! :D Java Language Specifications, (http://java.sun.com/docs/books/jls/).

Ho messo il riferimento perchè non molto tempo fa sparai una puttanata sull'operatore punto che mi brucia ancora :fagiano:. Faccio ammenda riguardando le specifiche ogni volta che intendo aprir bocca. Metto il riferimento perchè può essere interessante andare a vedere come sia formalmente espressa la regola e perchè, trattandosi di uno scritto, l'errata interpretazione è sempre dietro l'angolo. Insomma, vedere per decidere se credere.

nuovoUtente86
01-08-2007, 09:51
Infedele!!! :D Java Language Specifications, (http://java.sun.com/docs/books/jls/).

Ho messo il riferimento perchè non molto tempo fa sparai una puttanata sull'operatore punto che mi brucia ancora :fagiano:. Faccio ammenda riguardando le specifiche ogni volta che intendo aprir bocca. Metto il riferimento perchè può essere interessante andare a vedere come sia formalmente espressa la regola e perchè, trattandosi di uno scritto, l'errata interpretazione è sempre dietro l'angolo. Insomma, vedere per decidere se credere.Per curiosotà cosa hai sparato sul "punto"?
Per membri secondo te è corretto parlare di variabili,metodi e costruttori o solo di variabili?

In qualche post su parlavi di accessibilità per i Tipi..ma concretamente che vuol dire?

PGI-Bis
01-08-2007, 11:10
Una cosa tipo "se vede un punto il compilatore cerca il metodo nel tipo runtime", una baggianata colossale, come se un compilatore potesse navigare nel futuro.

Sull'accesso, le specifiche dicono che si applica all'accesso qualificato, all'invocazione di costruttori attraverso espressioni di creazione di istanza e alle invocazioni esplicite di costruttore.

L'accesso qualificato raggruppa tre fenomeni. L'accesso ai membri di un package e di riferimenti, l'accesso ai campi e le espressioni di invocazioni di metodo. (JLS 6.6).

Scartabellando si trova quindi che i "membri di un package" sono i sottopackage e i tipi classe e interfaccia top-level (cioè non interni) dichiarati in quel package.

Questo ci dice che è accesso, e quindi soggetto al controllo di accesso, anche una cosa tipo:

public class Pippo {
java.util.Vector p;
}

"java.util.Vector" è accesso qualificato a un tipo classe top-level membro del package util, sottopackage di java.