JAVA ΕΝΟΤΗΤΑ 6 – Integers (Part 2)

 


ΕΙΣΑΓΩΓΗ

Στο σημερινό δωρεάν μάθημα Java θα παραμείνουμε στα Integer Data Types για να δούμε αναλυτικά το Long data type

Επίσης θα δούμε πως μπορούμε να μετατρέψουμε ένα variable από ένα data type σε ένα άλλο (π.χ. από int σε Long και αντίστροφα) με την διαδικασία του casting. Τέλος θα δούμε πως ορίζουμε constants, δηλαδή variables στις οποίες δεν επιτρέπεται η αλλαγή της αρχικής τιμής και τι ακριβώς είναι το type inference.

DEFINING A LONG DATA TYPE

Όπως είχαμε αναφέρει και στο προηγούμενο δωρεάν μάθημα Java, το long είναι ένα 64-bit Java primitive data type. Συνήθως το χρησιμοποιούμε όταν θέλουμε να αναφερθούμε σε αρκετά μεγάλους ακέραιους αριθμούς τους οποίους δεν μπορούμε να τους περιγράψουμε με το int data type των 32-bit.

Ο λόγος που αναφερόμαστε σε αυτό το data type είναι επειδή η Java, όσο αφορά τα integral data types, έχει το int σαν το default data type. Αυτό, με απλά λόγια, σημαίνει ότι όλους τους ακέραιους αριθμούς η Java προσπαθεί να τους μετατρέψει σε int. Οπότε για να μπορέσουμε να δηλώσουμε ένα long data type δεν είναι μόνο αρκετό να δηλώσουμε το Long σαν data type αλλά θα πρέπει να προσθέσουμε και το γράμμα l ή L στο τέλος του αριθμού. Επειδή το lowercase l δεν ξεχωρίζει τόσο εύκολα, συνήθως χρησιμοποιούμε το uppercase L.

long num = 123456789L;

Ας δούμε ένα απλό παράδειγμα στο οποίο χρησιμοποιούμε variables με long data types. Αφού δημιουργήσουμε μια κλάση και προσθέσουμε την main( ) μέθοδο, ορίζουμε μια variable με το όνομα spaceshipSpeed. Το πρόγραμμα υπολογίζει πόσα χιλιόμετρα θα διανύσει το διαστημόπλοιο μετά από τρία χρόνια.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        Long spaceshipSpeed;
        long days;
        long distance;

        // Spaceship speed per day
        spaceshipSpeed = 299792L;
        // 3 years
        days = 1095;
        // distance after 3 years
        distance = spaceshipSpeed * days; // compute distance
        System.out.println("In " + days + " days the spaceship will travel "+ distance + " kilometers");

    }
}

Output

In 1095 days the spaceship will travel 328272240 kilometers


Αν θέλετε να μάθετε πόσο μεγάλος είναι ένας long αριθμός, τότε μπορείτε να αναθέσετε την τιμή Long.MAX_VALUE σε μια long variable και να τυπώσετε την τιμή της στο terminal. Αντίστοιχα θα μπορούσατε να μάθετε με το Long.MIN_VALUE ποια είναι η κατώτερη τιμή που μπορεί να έχει ένας long αριθμός. Ας προσθέσουμε λοιπόν και αυτές τις δύο μεταβλητές στο πρόγραμμα μας.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        Long spaceshipSpeed;
        long days;
        long distance;

        // Spaceship speed per day
        spaceshipSpeed = 299792L;
        // 3 years
        days = 1095;
        // distance after 3 years
        distance = spaceshipSpeed * days; // compute distance
        System.out.println("In " + days + " days the spaceship will travel "+ distance + " kilometers");

        // Desired distance after 10 years
        long finalDistance = Long.MAX_VALUE;
        System.out.println("Some day our starship will" + " be fast enough to cover "
+ finalDistance + " kilometers in 10 years");

    }
}

Output

In 1095 days the spaceship will travel 328272240 kilometers

Some day our starship will be fast enough to cover 9223372036854775807 kilometers in 10 years


CASTING

Στο προγραμματισμό είναι πολύ συνηθισμένο φαινόμενο να αναθέτουμε την τιμή μιας μεταβλητής σε μια άλλη μεταβλητή. Εάν τα data types των δύο μεταβλητών είναι συμβατά μεταξύ τους, τότε η Java θα κάνει αυτόματα τη μετατροπή από το ένα data type στο άλλο. Για παράδειγμα, μια int variable μπορεί να αναθέσει την τιμή της σε μια long variable χωρίς να χρειαστεί η δική μας παρέμβαση. Αυτή η αυτόματη διαδικασία ονομάζεται widening  conversion και είναι εφικτή γιατί μια int variable που αναφέρεται σε έναν αριθμό με 32-bits μπορεί να χωρέσει και να περιγραφτεί σωστά από μια long variable των 64-bits χωρίς να χάσουμε σε ακρίβεια.


 

Υπάρχουν όμως περιπτώσεις όπου θέλουμε να εκτελέσουμε την ακριβώς αντίθετη λειτουργία – δηλαδή να αναθέσουμε μια long variable σε μια int variable. Σε αυτή την περίπτωση η Java δεν αναλαμβάνει την ευθύνη να πραγματοποιήσει αυτόματη τροποποίηση γιατί μπορεί να αλλοιωθεί η ακρίβεια του αποτελέσματος. Μπορούμε όμως να αναλάβουμε εμείς προγραμματιστικά να πραγματοποιήσουμε την πράξη του narrowing conversion χρησιμοποιώντας casting.

Με το casting δηλώνουμε σε ποιο data type επιθυμούμε να μετατρέψουμε έναν αριθμό πριν το αναθέσουμε τελικά στη μεταβλητή. Η σύνταξη της casting εκτέλεσης είναι απλή – μέσα σε παρένθεση γράφουμε το επιθυμητό data type και αμέσως μετά, έξω από την παρένθεση, ακολουθεί το όνομα της μεταβλητής της οποίας την τιμή θέλουμε να μετατρέψουμε.

Ας δούμε ένα απλό παράδειγμα μέσα από το οποίο μπορείτε να καταλάβετε καλύτερα την χρησιμότητα και λειτουργία του casting.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        int var1 = 10;
        long var2;
        // Automating conversion
        var2 = var1;
        System.out.println("The final value of var2 is " + var2);

        int var3;
        long var4 = 25L;
        // Casting
        var3 = (int) var4;
        System.out.println("The final value of var3 is " + var3);

    }
}


Output

The final value of var2 is 10

The final value of var3 is 25


        var2 = var1;

Σε αυτή τη γραμμή κώδικα, η var1 μεταβλητή θα ελεγχθεί πρώτη και θα βρεθεί να είναι int 32-bit. Μετά θα ελεγχθεί η var2 και θα βρεθεί να είναι long 64-bit. Ένας αριθμός των 32 bits μπορεί να ανατεθεί σε μια μεταβλητή με περισσότερα bits, από την ίδια κατηγορία data type, χωρίς να υπάρχει φόβος ότι θα λάβουμε λανθασμένο αποτέλεσμα. Εδώ η Java εκτελεί τη μετατροπή αυτόματα και δέχεται την ανάθεση.


        var3 = (int) var4;

Σε αυτή τη γραμμή κώδικα, αν και η var4 variable περιέχει την τιμή 25 που άνετα «χωράει» σε μια int variable, η Java δεν το υπολογίζει αυτό. Αυτό που ελέγχει, και κατά συνέπεια εμποδίζει την διαδικασία της αυτόματης μετατροπής, είναι η ανάθεση ενός 64-bit αριθμού σε μια 32-bit μεταβλητή. Μπορεί η μεταβλητή να έχει την τιμή 25, αλλά η Java θεωρεί ότι κάλλιστα ο αριθμός θα μπορούσε να είναι ο μέγιστος αριθμός που μπορεί να πάρει μια long μεταβλητή. Με αυτή τη λογική λοιπόν σαν κανόνα, η Java δεν εκτελεί την αυτόματη μετατροπή από long σε int αλλά αφήνει την ευθύνη στο προγραμματιστή. Στη συγκεκριμένη γραμμή κώδικα, η Java διαβάζει πρώτα την τιμή var4 και μετά την μετατρέπει σε int ακολουθώντας το casting type που έχουμε ορίσει μέσα στη παρένθεση. Τώρα που εκτελέστηκε το casting γίνεται η ανάθεση του αριθμού στη μεταβλητή var3.

Με την ίδια λογική μπορούμε να μετατρέψουμε μια μεταβλητή από short σε byte ή από int σε short. Την έννοια του casting θα την συναντήσουμε πολλές φορές ακόμα κυρίως όταν μιλήσουμε για αντικείμενα.

Οι long μεταβλητές περιγράφουν αρκετά μεγάλους αριθμούς. Η Java μας επιτρέπει να γράψουμε αυτούς τους αριθμούς με κάπως πιο φιλική μορφή χρησιμοποιώντας το underscore ( _ ) . Αυτή την ιδιότητα ίσως την βρείτε χρήσιμη όταν θέλετε να διαβάσετε γρήγορα έναν αριθμό που περιέχει πολλά ψηφία. Εσωτερικά η Java διαχειρίζεται τον αριθμό όπως το γνωρίζουμε στην κανονική του μορφή. Το συγκεκριμένο στυλ δήλωσης ενός long αριθμού είναι εντελώς προσωπική απόφαση.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        int var1 = 10;
        long var2 = 20L;
        // Automating conversion
        var2 = var1;
        System.out.println("The final value of var2 is " + var2);

        int var3 = 5;
        long var4 = 25L;
        var3 = (int) var4;
        System.out.println("The final value "
        +"of var3 is " + var3);
        // Instead of 123456789
        long longNum = 1_234_456_789;
        System.out.println("The longNum variable "+"contains the number " + longNum);

    }
}

Output

The final value of var2 is 10

The final value of var3 is 25

The longNum variable contains the number 1234456789


TYPE INFERENCE

Από τη Java version 10, οι τοπικές μεταβλητές μπορούν να δηλωθούν με την λέξη κλειδί var και ο compiler της Java θα αποφασίσει αυτόματα το data type της μεταβλητής με βάση την τιμή που της αναθέτουμε.

Για να μπορέσουμε να χρησιμοποιήσουμε το var με τις μεταβλητές, η Java απαιτεί να ορίσουμε τη μεταβλητή και να της αναθέσουμε μια τιμή την ίδια στιγμή όπως δείχνει και το παρακάτω παράδειγμα.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        var var1 = 10;
        var var2 = 20L;
        // Automating conversion
        var2 = var1;
        System.out.println("The final value of var2 is " + var2);

        var var3 = 5;
        var var4 = 25L;
        var3 = (int) var4;
        System.out.println("The final value of var3 is " + var3);
        // Instead of 123456789
        long longNum = 1_234_456_789;
        System.out.println("The longNum variable " + "contains the number " + longNum);

    }
}

Output

The final value of var2 is 10

The final value of var3 is 25

The longNum variable contains the number 1234456789


CONSTANTS

Κάποια στιγμή στο κώδικα μας θα έχουμε τιμές που δεν θα επιθυμούμε προγραμματιστικά να είναι δυνατόν να αλλάξουν. Για παράδειγμα, ο φόρος που ισχύει για πωλήσεις προϊόντων, η μετατροπή από μίλια σε χιλιόμετρα, κτλ. Για να το πετύχουμε αυτό, η Java επιθυμεί από εμάς να προσθέσουμε την λέξη κλειδί final μπροστά από το data type της μεταβλητής.

Όταν η μεταβλητή δεχτεί την πρώτη της τιμή, τότε δεν θα επιτρέψει καμία περαιτέρω αλλαγή σε αυτήν. Στο παρακάτω απλό παράδειγμα, ορίζουμε την έκπτωση που κάνουμε στην αρχική τιμή ενός προϊόντος σαν final. Αυτό σημαίνει ότι προγραμματιστικά δεν μπορούμε να αλλάξουμε την τιμή – δηλαδή μέσα στο κώδικα μας να προσπαθήσουμε να αναθέσουμε μια καινούργια τιμή. Αν επιθυμούμε να κάνουμε αλλαγή της τιμής, αυτή πρέπει να γίνει με αλλαγή στην αρχική δήλωση της μεταβλητής.

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        var original_item_price = 25;
        final var discount_coupon = 10;
        var sale_price = original_item_price - discount_coupon;
        System.out.println("The final sale price is " + sale_price);
    }
}

Output

The final sale price is 15


Αν προγραμματιστικά προσπαθήσετε να αναθέσετε καινούργια τιμή στη μεταβλητή discount_coupon θα λάβετε το εξής λάθος:

App.java

package com.example;

public class App {

    public static void main(String[] args) {
        var original_item_price = 25;
        final var discount_coupon = 10;
        var sale_price = original_item_price - discount_coupon;
        System.out.println("The final sale price is "+ sale_price);
        System.out.println("Let's change the discount offered");
        discount_coupon = 12;
    }
}

Output

Exception in thread "main" java.lang.Error: Unresolved compilation problem:

The final local variable discount_coupon cannot be assigned. It must be blank and not using a compound assignment

 at com.example.App.main(App.java:11)

 

Μην ξεχάσετε να κάνετε ένα μικρό donation έτσι ώστε αυτό το blog να μεγαλώσει ακόμα πιο πολύ και να έχει περισσότερες δυνατότητες στην online παράδοση δωρεάν μαθημάτων.

full-width

Post a Comment

0 Comments