Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.
class Test {

   int a, b;

 

   Test(int i, int j) {

   a = i;

   b = j;

    }

 

    void meth(Test o) {

        o.a *= 2;

        o.b /= 2;

     }

}

 

class CallByRef {

    public static void main(String args[]) {

         Test ob = new Test(15, 20);

         System.out.println("ob.a and ob.b before call: " + ob.a + " " + ob.b );

         ob.meth(ob);

         System.out.println("ob.a and ob.b after call: " + ob.a + " " + ob.b );

         }

}

 

Όπως βλέπετε τα a και b μετα την κλήση της ob.meth(ob) θα αλλάξουν οι τιμές τους. Τώρα, το ερώτημα είναι, είναι αυτός λόγος να θεωρήσει κανείς ότι αυτό το παράδειγμα κάνει την Java pass-by-reference;

Σύμφωνα με τον καθηγητή μου, ναι, είναι ένας λόγος. Απο την άλλη διαβάζω σε πολλά site πως η Java δεν έχει τίποτα να κάνει με pass-by-reference, πως το reference στην Java είναι απλά μια τιμή και δεν έχει την έννοια του pointer. 

 

Τι λέτε εσείς; Έχω μπερδευτεί πολύ άσχημα.

Δημοσ.

δε διαφωνώ σε αυτό, πιο πολυ για τα υπόλοιπα που λέει το έβαλα, ωστόσο για τη c λέει ξεκάθαρα οτι είναι pass by value όπως η java

είτε περνάς τη μεταβλητή by value είτε περνάς έναν pointer στη μεταβλητή πάλι by value

Δημοσ.

Το διάβασα το παραπάνω άρθρο.

 

Άρα λοιπόν, σύμφωνα με το άρθρο:

"Java works exactly like C. You can assign a pointer, pass the pointer to a method, follow the pointer in the method and change the data that was pointed to. However, you cannot change where that pointer points."

βγάζουμε το συμπέρασμα ότι το παραπάνω παράδειγμα που παρέθεσα είναι άσχετο με αυτό που προσπαθεί να δείξει ο καθηγητής μου, σωστά;

 

Τώρα το θέμα είναι πως θα πρέπει να ανταποκριθώ αν υπάρξει τέτοια ερώτηση στο διαγώνισμα.

Δημοσ.

Ta a,b είναι members της class. Δεν τα πέρασες ως παραμέτρους σε κάποια συναστήση να δεις αν αλλάζουν η όχι.

Tο παράδειγμα δεν έχει σχέση με pass by value/reference.

x=15, y=20;
Test ob = new Test(x, y);
ob.meth(ob);

Τα x,y δεν θα αλλάξουν.

  • Like 2
  • Moderators
Δημοσ.

δε διαφωνώ σε αυτό, πιο πολυ για τα υπόλοιπα που λέει το έβαλα, ωστόσο για τη c λέει ξεκάθαρα οτι είναι pass by value όπως η java

είτε περνάς τη μεταβλητή by value είτε περνάς έναν pointer στη μεταβλητή πάλι by value

 

Πιο πολύ το έγραψα για να μη μπερδευτεί ο Χρήστος ή κάποιος άλλος που έχει παρόμοια ερώτηση.

 

 

Τώρα το θέμα είναι πως θα πρέπει να ανταποκριθώ αν υπάρξει τέτοια ερώτηση στο διαγώνισμα.

 

Θα πεις ότι το μόνο που υποστηρίζει η Java είναι pass-by-value.

Δημοσ.

Όταν αυτό που περνάει είναι δείκτης σε κάτι, τότε αν και είναι By Value, δηλαδή μια αντιγραφή τιμής, εδώ της τιμής του δείκτη, και όχι αυτό που δείχνει ο δείκτης, είναι στην ουσία πέρασμα By Reference. Δεν θα είχαμε By Reference αν περνάγαμε το αντίγραφο ενός αντικειμένου, με νέο δείκτη στο νέο αντικείμενο (το αντίγραφο). Τα αντικείμενα επειδή μένουν στη Heap, περνάνε πάντα με δείκτη που μένει στο Stack, είναι Local δηλαδή!

Δημοσ.

Σύμφωνα με τον καθηγητή μου, ναι, είναι ένας λόγος.

 

Ο καθηγητής σου λέει βλακείες και μπερδεύει τους μαθητές του.

 

Στο κλασικό σενάριο που παρέθεσες, περνάει by value μια τιμή η οποία τυχαίνει αντί για π.χ. integer να είναι object reference. Τίποτα λιγότερο και τίποτα περισσότερο.

 

Ρώτα αν θες τον καθηγητή σου, μπά ξέρεις τι, εγώ λέω πως η συμπεριφορά που βλέπουμε σημαίνει ότι το argument που περνάμε είναι pointer άρα η Java έχει pointers, να δούμε πώς θα το καταρρίψει αυτό με τρόπο που να μη μπορεί να εφαρμοστεί ενάντια και στη δική του τοποθέτηση.

Δημοσ.

Θα τον ρωτήσω. Βέβαια ο καλύτερος τρόπος να του δείξω ότι αυτό που λέει δεν ισχύει είναι μέσω του specification της java. Το θέμα είναι ότι λέει κάτι περίεργα που δεν τα καταλαβαίνω :P Ίσως καθίσω να το διαβάσω πιο προσεκτικά.

 

Πάντως να τονίσω πως δεν θέλω να του την πω ή κάτι τέτοιο. Απλά αν μπορεί να το διορθώσει γιατί τις σημειώσεις του τις διαβάζουν πολλοί μαθητές με αποτέλεσμα να βρεθούν αντιμέτωποι με κάτι παρόμοιο και να μην ξέρουν τι τους γίνεται.

Δημοσ.

Εσύ καλά κάνεις και δεν πας να του την πεις, προφανώς δεν έχει κανένα νόημα αυτό και θα ήταν χαζό.

 

Εμείς από την άλλη που δεν τον ξέρουμε...  :P

 

 

ΥΓ πάει πολύς καιρός που έπιασα το JLS στα χέρια μου, αλλά γενικά δε θα βρεις πουθενά να λέει κανείς "η γλώσσα μας περνάει by reference". Το τι ακριβώς κάνει η γλώσσα προκύπτει από το κατά πόσο ταιριάζουν αυτά που περιγράφει το spec με την ιδέα που έχει ο καθένας στο μυαλό του για το τι είναι by value/by ref.

  • Like 1
Δημοσ.

Ναι, το να την πει στον Καθηγητή του είναι λάθος. Εξάλλου, αν κάτι μπορεί να έχει το ίδιο αποτέλεσμα με το By Reference  πέρασμα τιμής, μπορεί να θεωρηθεί ότι είναι By Reference πέρασμα (και ας είναι τεχνικά αντιγραφή δείκτη, δηλαδή By value πέρασμα του δείκτη).

Η java όμως αφού περνάει τα πάντα By Value, δεν μπορούμε να πούμε το αντίθετο, ή ότι "μερικώς περνάει By Reference". Μας σώνει ο φορμαλισμός Έμμεσα γίνεται να έχουμε By Reference στη Java. Έτσι δεν σπάμε την βασική ιδέα ότι όλα περνάνε By Value.

Δημοσ.

Δεν μπορείς να πεις ότι είναι έμμεσα by reference, επειδή έχει άλλα τεχνικά χαρακτηριστικά. Αλλά μπορείς να πεις ότι το object obj; Είναι reference. Στο λέω αυτό επειδή η c# που είναι κοντά στη java, έχει και pass by reference άσχετα που και εκεί το object είναι reference.

Δημοσ.

Αν μείνουμε στο ότι by reference σημαίνει απλά "μπορούμε να επιστρέψουμε κάτι που δώσαμε με αλλαγές" τότε αυτό στη java γίνεται σε αντικείμενα που μπορούν να αλλάξουν. Αν τώρα θέλουμε  να αλλάξει το αντικείμενο με ένα άλλο, και αυτό να επιστραφεί, στη java δεν γίνεται. Το ερώτημα είναι...γιατί να το κάνουμε αυτό;

 

Προφανώς αν αλλάξω τα πάντα σε ένα αντικείμενο, τότε αυτό θα είναι κάτι άλλο! Τι θα με βολέψει να δημιουργήσω νέο ίδιο αντικείμενο (με άλλες τιμές, άλλη κατάσταση) και να το δώσω στη θέση του παλιού;

Δημοσ.

Αν μείνουμε στο ότι by reference σημαίνει απλά "μπορούμε να επιστρέψουμε κάτι που δώσαμε με αλλαγές" τότε αυτό στη java γίνεται σε αντικείμενα που μπορούν να αλλάξουν. Αν τώρα θέλουμε  να αλλάξει το αντικείμενο με ένα άλλο, και αυτό να επιστραφεί, στη java δεν γίνεται. Το ερώτημα είναι...γιατί να το κάνουμε αυτό;

 

Προφανώς αν αλλάξω τα πάντα σε ένα αντικείμενο, τότε αυτό θα είναι κάτι άλλο! Τι θα με βολέψει να δημιουργήσω νέο ίδιο αντικείμενο (με άλλες τιμές, άλλη κατάσταση) και να το δώσω στη θέση του παλιού;

 

1. Με αυτή τη λογική, άμα περάσω ένα file descriptor (ας πούμε πως είναι integer) σε μια συνάρτηση και διαβάσω κάτι από εκεί, τότε μετά την επιστροφή της συνάρτησης έχω κάνει αλλαγές που ο caller μπορεί να παρατηρήσει (ας πούμε διαβάζοντας την τρέχουσα θέση του file pointer) και άρα ο απλός integer πέρασε με reference.

 

2. Η ερώτηση είναι ρητορική, ή το λες επειδή δεν ξέρεις και θέλεις να μάθεις; Γιατί αν είναι ρητορική ίσως πρέπει να λάβεις υπόψη πως όλοι οι language designers ανά τα χρόνια που έβαλαν στις γλώσσες τους references ίσως έχουν λάβει υπόψη σενάρια που εσύ δεν έχεις σκεφτεί.

 

Granted, πρακτικά είναι πολύ πολύ δύσκολο να βρεις σενάριο που γίνεται με reference και δε γίνεται χωρίς, αλλά αυτό δε λέει και πολλά. Είναι επίσης αδύνατο να βρεις σενάριο που γίνεται με for και δε γίνεται με do while, παρόλα αυτά όμως "όλες" οι γλώσσες έχουν και for και do while. Ίσως αυτό είναι ένα ερώτημα του οποίου η απάντηση μπορεί πολύ πιο εύκολα να γίνει κατανοητή επειδή έχει να κάνει με πιο απλά χειροπιαστά πράγματα.

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...