صفحة 3 من 3 الأولىالأولى 123
النتائج 31 إلى 36 من 36

الموضوع: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

  1. #31
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    Chapter 12

    Java language fundamentals

    Java is an object-oriented language. This means that the language is based on the concept of an object. Although a knowledge of object-oriented programming is necessary to put Java to practical use, it isn’t required to understand the fundamentals of the Java language. This chapter focuses on the language and leaves the object-oriented details of Java for Chapter 14, “Classes, Packages, and Interfaces.”

    If you already have some experience with another object-oriented language such as C++ or Smalltalk, much of Java will be familiar territory. In fact, Java almost can be considered a new, revamped C++. Because Java is so highly derived from C++, many of the similarities and differences between Java and C++ will be highlighted throughout the next few chapters. Additionally, Appendix D provides a more thorough look at the differences between Java and C++.

    This chapter covers the essentials of the Java language, including a few sample programs to help you hit the ground running.

    Hello, World!

    The best way to learn a programming language is to jump right in and see how a real program works. In keeping with a traditional introductory programming example, your first program will be a Java version of the classic “Hello, World!” program. Listing 12.1 contains the source code for the HelloWorld class, which also is located on the CD-ROM in the file HelloWorld.java.

    NOTEYou may be thinking that you’ve already said hello to the world with Java in Chapter 2, “Java’s Design Is Flexible and Dynamic.” The HelloWorld program you saw in Chapter 2 was a Java applet, meaning that it ran within the confines of a Web page and printed text as graphical output. The HelloWorld program in this chapter is a Java application, which means that it runs within the Java interpreter as a stand-alone program and has text output.

    • Listing 12.1. The HelloWorld class.
    class HelloWorld { public static void main (String args[]) { System.out.println(“Hello, World!”); }}After compiling the program with the Java compiler (javac), you are ready to run it in the Java interpreter. The Java compiler places the executable output in a file called HelloWorld.class. This naming convention might seem strange considering the fact that most programming languages use the .EXE file extension for executables. Not so in Java! Following the object-oriented nature of Java, all Java programs are stored as Java classes that are created and executed as objects in the Java run-time environment. To run the HelloWorld program, type java HelloWorld at the command prompt. As you may have guessed, the program responds by displaying “Hello, World!” on your screen. Congratulations—you just wrote and tested your first Java program!

    As you might have guessed, HelloWorld is a very minimal Java program. Even so, there’s still a lot happening in those few lines of code. To fully understand what is happening, you need to examine the program line by line. First, you need to understand that Java relies heavily on classes. In fact, the first statement of HelloWorld reminds you that HelloWorld is a class, not just a program. Furthermore, looking at the class statement in its entirety, the name of the class is defined as HelloWorld. This name is used by the Java compiler as the name of the executable output class. The Java compiler creates an executable class file for each class defined in a Java source file. If there is more than one class defined in a .java file, the Java compiler will store each one in a separate .class file. It isn’t strictly necessary to give the source file the same name as the class file, but it is highly recommended as a style guideline.

    The HelloWorld class contains one method, or member function. For now, you can think of this function as a normal procedural function that happens to be linked to the class. The details of methods are covered in Chapter 14, “Classes, Packages, and Interfaces.” The single method in the HelloWorld class is called main, and should be familiar if you have used C or C++. The main method is where execution begins when the class is executed in the Java interpreter. The main method is defined as being public static with a void return type. public means that the method can be called from anywhere inside or outside of the class. static means that the method is the same for all instances of the class. The void return type means that main does not return a value.

    The main method is defined as taking a single parameter, String args[]. args is an array of String objects that represents command-line arguments passed to the class upon execution. Because HelloWorld doesn’t use any command-line arguments, you can ignore the args parameter. You’ll learn a little more about strings later in this chapter.

    The main method is called when the HelloWorld class is executed. main consists of a single statement that prints the message “Hello, World!” to the standard output stream, as follows:

    System.out.println(“Hello, World!”);This statement might look a little confusing at first because of the nested objects. To help make things clearer, examine the statement from right to left. First notice that the statement ends in a semicolon, which is standard Java syntax that has been borrowed from C/C++. Moving on to the left, you see that the “Hello, World!” string is in parentheses, which means it is a parameter to a function call. The method being called is actually the println method of the out object. The println method is similar to the printf method in C, except that it automatically appends a newline (\n) at the end of the string. The out object is a member variable of the System object that represents the standard output stream. Finally, the System object is a global object in the Java environment that encapsulates system functionality.

    That pretty well covers the HelloWorld class—your first Java program. If you got lost a little in the explanation of the HelloWorld class, don’t be too concerned. HelloWorld was presented with no prior explanation of the Java language and was only meant to get your feet wet with Java code. The rest of this chapter focuses on a more structured discussion of the fundamentals of the Java language.

    Tokens

    When you submit a Java program to the Java compiler, the compiler parses the text and extracts individual tokens. A token is the smallest element of a program that is meaningful to the compiler. This actually is true for all compilers, not just the Java compiler. These tokens define the structure of the Java language. All of the tokens that comprise Java are known as the Java token set. Java tokens can be broken down into five categories: identifiers, keywords, literals, operators, and separators. The Java compiler also recognizes and subsequently removes comments and whitespaces.

    The Java compiler removes all comments and whitespaces while tokenizing the source file. The resulting tokens then are compiled into machine-independent Java bytecode that is capable of being run from within an interpreted Java environment. The bytecode conforms to the hypothetical Java Virtual Machine, which abstracts processor differences into a single virtual processor. For more information on the Java Virtual Machine, check out Chapter 39, “Java’s Virtual Machine, Bytecodes, and More.” Keep in mind that an interpreted Java environment can be either the Java command-line interpreter or a Java-capable browser.

    Identifiers

    Identifiers are tokens that represent names. These names can be assigned to variables, methods, and classes to uniquely identify them to the compiler and give them meaningful names to the programmer. HelloWorld is an identifier that assigns the name HelloWorld to the class residing in the HelloWorld.java source file developed earlier.

    Although you can be creative in naming identifiers in Java, there are some limitations. All Java identifiers are case-sensitive and must begin with a letter, an underscore (_), or a dollar sign ($). Letters include both upper- and lowercase letters. Subsequent identifier characters can include the numbers 0 to 9. The only other limitation to identifier names is that the Java keywords, which are listed in the next section, cannot be used. Table 12.1 contains a list of valid and invalid identifier names.

    Table 12.1. Valid and invalid Java identifiers.

    ValidInvalid

    HelloWorldHello WorldHi_MomHi_Mom!heyDude3 3heyDudetallshortpoundage#age

    The Hello World identifier is invalid because it contains a space. The Hi_Mom! identifier is invalid because it contains an exclamation point. The 3heyDude identifier is invalid because it begins with a number. The short identifier is invalid because short is a Java keyword. Finally, the #age identifier is invalid because it begins with the # symbol.

    Beyond the mentioned restrictions of naming Java identifiers, there are a few stylistic rules you should follow to make Java programming easier and more consistent. It is standard Java practice to name multiple-word identifiers in lowercase except for the beginning letter of words in the middle of the name. For example, the variable toughGuy is in correct Java style, whereas toughguy, ToughGuy, and TOUGHGUY are all in violation. This rule isn’t etched in stone—it’s just a good idea to follow because most other Java code you run into will follow this style. Another more critical naming issue regards the use of underscore and dollar sign characters at the beginning of identifier names. This is a little risky because many C libraries use the same naming convention for libraries, which can be imported into your Java code. To eliminate the potential problem of name clashing in these instances, it’s better to stay away from the underscore and dollar sign characters at the beginning of your identifier names. A good usage of the underscore character is to separate words where you normally would use a space.

    Keywords

    Keywords are predefined identifiers reserved by Java for a specific purpose and are used only in a limited, specified manner. Java has a richer set of keywords than C or C++, so if you are learning Java with a C/C++ background, be sure to pay attention to the Java keywords. The following keywords are reserved for Java:

    abstract double int superboolean else interface switchbreak extend long synchronizedbyte false native thisbyvalue final new threadsafecase finally null throwcatch float package transientchar for private trueclass goto protected tryconst if public voidcontinue mplements return whiledefault import shortdoinstanceofstatic



    Literals

    Program elements that are used in an invariant manner are called literals or constants. Literals can be numbers, characters, or strings. Numeric literals include integers, floating-point numbers, and Booleans. Booleans are considered numeric because of the C influence on Java. In C, the Boolean values for true and false are represented by 1 and 0. Character literals always refer to a single Unicode character. Strings, which contain multiple characters, still are considered literals even though they are implemented in Java as objects.

  2. #32
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    NOTEIf you aren’t familiar with the Unicode character set, it is a 16-bit character set that replaces the ASCII character set. Because it is 16 bit, there are enough entries to represent many symbols and characters from other languages. Unicode is quickly becoming the standard for modern operating systems.

    Integer Literals

    Integer literals are the primary literals used in Java programming and come in a few different formats: decimal, hexadecimal, and octal. These formats correspond to the base of the number system used by the literal. Decimal (base 10) literals appear as ordinary numbers with no special notation. Hexadecimal numbers (base 16) appear with a leading 0x or 0X, similar to C/C++. Octal (base 8) numbers appear with a leading 0 in front of the digits. For example, an integer literal for the decimal number 12 is represented in Java as 12 in decimal, 0xC in hexadecimal, and 014 in octal.

    Integer literals default to being stored in the int type, which is a signed 32-bit value. If you are working with very large numbers, you can force an integer literal to be stored in the long type by appending an l or L to the end of the number, as in 79L. The long type is a signed 64-bit value.

    Floating-Point Literals

    Floating-point literals represent decimal numbers with fractional parts, such as 3.142. They can be expressed in either standard or scientific notation, meaning that the number 563.84 also can be expressed as 5.6384e2.

    Unlike integer literals, floating-point literals default to the double type, which is a 64-bit value. You have the option of using the smaller 32-bit float type if you know the full 64 bits are not needed. You do this by appending an f or F to the end of the number, such as 5.6384e2f. If you are a stickler for details, you also can explicitly state that you want a double type as the storage unit for your literal, such as 3.142d. Because the default storage for floating-point numbers is double already, this isn’t necessary.

    Boolean Literals

    Boolean literals are certainly a welcome addition if you are coming from the world of C/C++. In C, there is no Boolean type, and therefore no Boolean literals. The Boolean values True and False are represented by the integer values 1 and 0. Java fixes this problem by providing a boolean type with two possible states: true and false. Not surprisingly, these states are represented in the Java language by the keywords true and false.

    Boolean literals are used in Java programming about as often as integer literals because they are present in almost every type of control structure. Any time you need to represent a condition or state with two possible values, a boolean is what you need. You’ll learn a little more about the boolean type later in this chapter. For now, just remember the two Boolean literal values: true and false.

    Character Literals

    Character literals represent a single Unicode character and appear within a pair of single quotation marks. Similar to C/C++, special characters (control characters and characters that cannot be printed) are represented by a backslash (\) followed by the character code. A good example of a special character is \n, which forces the output to a new line when printed. Table 12.2 shows the special characters supported by Java.

    Table 12.2. Special characters supported by Java.

    DescriptionRepresentationBackslash\\Continuation\Backspace\bCarriage Return,/td> \rForm Feed\fHorizontal Tab\t Newline\nSingle Quote\’Double Quote\”Unicode Character\uddddOctal Number\ddd

    An example of a Unicode character literal is \u0048, which is a hexadecimal representation of the character H. This same character is represented in octal as \110.

    String Literals

    String literals represent multiple characters and appear within a pair of double quotation marks. Unlike all of the other literals discussed, string literals are implemented in Java by the String class. This is very different from the C/C++ representation of strings as an array of characters.

    When Java encounters a string literal, it creates an instance of the String class and sets its state to the characters appearing within the double quotes. From a usage perspective, the fact that Java implements strings as objects is relatively unimportant. However, it is worth mentioning at this point because it is a reminder that Java is very object oriented in nature—much more than C++, which is widely considered the current object-oriented programming standard.

    Operators

    Operators, also known as operands, specify an evaluation or computation to be performed on a data object or objects. These operands can be literals, variables, or function return types. The operators supported by Java follow:

    +-*/%&|^~&&||!<><=>=<<>>>>>=?++- -==+=-=*=/=%=&=|=^=!=<<=>>=>>>=.[]()

    Just seeing these operators probably doesn’t help you a lot in determining how to use them. Don’t worry—you’ll learn a lot more about operators and how they are used in the next chapter, “Expressions, Operators, and Control Structures.”

    Separators

    Separators are used to inform the Java compiler of how things are grouped in the code. For example, items in a list are separated by commas much like lists of items in a sentence. Java separators go far beyond commas, however, as you’ll find out in the next chapter. The separators supported by Java follow:

    {};,:

    Comments and Whitespace

    Earlier you learned that comments and whitespace are removed by the Java compiler during the tokenization of the source code. You might be wondering, “What qualifies as whitespace and how are comments supported?” First, whitespace consists of spaces, tabs, and linefeeds. All occurrences of spaces, tabs, or linefeeds are removed by the Java compiler, as are comments. Comments can be defined in three different ways, as shown in Table 12.3.

    Table 12.3. Types of comments supported by Java.

    TypeUsage/* comment */ All characters between /* and */ are ignored.// comment All characters after the // up to the end of the line are ignored./** comment */ Same as /* */, except that the comment can be used with the javadoc tool to create automatic documentation.

    The first type of comment (/* comment */) should be familiar if you have programmed in C before. All characters inside the /* and */ comment delimiters are ignored by the compiler. Similarly, the second type of comment (// comment) also should be familiar if you have used C++. All characters appearing after the // comment delimiter up to the end of the line are ignored by the compiler. These two comment types are borrowed from C and C++. The final comment type (/** comment */) works in the same fashion as the C-style comment type, with the additional benefit that it can be used with the Java Automatic Documentation tool, javadoc, to create automatic documentation from the source code. The javadoc tool is covered in Chapter 37, “Java Documentation.” The following are a few examples of using the various types of comments:

    /* This is a C style comment. */// This is a C++ style comment./** This is a javadoc style comment. */

  3. #33
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    Data Types

    One of the fundamental concepts of any programming language is that of data types. Data types define the storage methods available for representing information, along with how the information is interpreted. Data types are linked tightly to the storage of variables in memory because the data type of a variable determines how the compiler interprets the contents of the memory. You already have received a little taste of data types in the discussion of literal types.

    To create a variable in memory, you must declare it by providing the type of the variable as well as an identifier that uniquely identifies the variable. The syntax of the Java declaration statement for variables follows:

    Type Identifier [, Identifier];The declaration statement tells the compiler to set aside memory for a variable of type Type with the name Identifier. The optional bracketed Identifier indicates that you can make multiple declarations of the same type by separating them with commas. Finally, as in all Java statements, the declaration statement ends with a semicolon.

    Java data types can be divided into two categories: simple and composite. Simple data types are core types that are not derived from any other types. Integer, floating-point, Boolean, and character types are all simple types. Composite types, on the other hand, are based on simple types, and include strings, arrays, and both classes and interfaces in general. You’ll learn about arrays later in this chapter. Classes and interfaces are covered in Chapter 14, “Classes, Packages, and Interfaces.”

    Integer Data Types

    Integer data types are used to represent signed integer numbers. There are four integer types: byte, short, int, and long. Each of these types takes up a different amount of space in memory, as shown in Table 12.4.

    Table 12.4. Java integer types.

    TypeSizebyte8 bitsshort16 bitsint32 bitslong64 bits

    To declare variables using the integer types, use the declaration syntax mentioned previously with the desired type. The following are some examples of declaring integer variables:

    int i;short rocketFuel;long angle, magnitude;byte red, green, blue;Floating-Point Data Types

    Floating-point data types are used to represent numbers with fractional parts. There are two floating-point types: float and double. The float type reserves storage for a 32-bit single-precision number and the double type reserves storage for a 64-bit double-precision number.

    Declaring floating-point variables is very similar to declaring integer variables. The following are some examples of floating-point variable declarations:

    float temperature;double windSpeed, barometricPressure;boolean Data Type

    The boolean data type is used to store values with one of two states: true or false. You can think of the boolean type as a 1-bit integer value, because 1 bit can have only two possible values: 1 or 0. However, instead of using 1 and 0, you use the Java keywords true and false. true and false aren’t just conveniences in Java; they are actually the only legal Boolean values. This means that you can’t interchangeably use Booleans and integers like in C/C++. To declare a Boolean value, just use the boolean type declaration:

    boolean gameOver;Character Data Type

    The character data type is used to store single Unicode characters. Because the Unicode character set is composed of 16-bit values, the char data type is stored as a 16-bit unsigned integer. You create variables of type char as follows:

    char firstInitial, lastInitial;Remember that the char type is useful only for storing single characters. If you come from a C/C++ background, you might be tempted to try to fashion a string by creating an array of chars. In Java this isn’t necessary because the String class takes care of handling strings. This doesn’t mean that you should never create arrays of characters, it just means that you shouldn’t use a character array when you really want a string. C and C++ do not distinguish between character arrays and strings, but Java does.

    Casting Types

    There will inevitably be times when you need to convert from one data type to another. The process of converting one data type to another is called casting. Casting often is necessary when a function returns a type different than the type you need to perform an operation. For example, the read member function of the standard input stream (System.in) returns an int. You must cast the returned int type to a char type before storing it, as in the following:

    char c = (char)System.in.read();The cast is performed by placing the desired type in parentheses to the left of the value to be converted. The System.in.read function call returns an int value, which then is cast to a char because of the (char) cast. The resulting char value is then stored in the char variable c.

    The storage size of the types you are attempting to cast is very important. Not all types will safely cast to other types. To understand this, consider the outcome of casting a long to an int. A long is a 64-bit value and an int is a 32-bit value. When casting a long to an int, the compiler chops off the upper 32 bits of the long value so it will fit into the 32-bit int. If the upper 32-bits of the long contain any useful information, it will be lost and the number will change as a result of the cast. Information loss also can occur when casting between different fundamental types, such as integer and floating-point numbers. For example, casting a double to a long would result in the loss of the fractional information, even though both numbers are 64-bit values.

    When casting, the destination type should always be equal to or larger in size than the source type. Furthermore, you should pay close attention to casting across fundamental types, such as floating-point and integer types. Table 12.5 lists the casts that are guaranteed to result in no loss of information.

    Table 12.5. Casts that result in no loss of information.

    From TypeTo Typebyteshort, char, int, long, float, doubleshortint, long, float, doublecharint, long, float, doubleintlong, float, doublelongfloat, doublefloatdouble

    Blocks and Scope

    In Java, source code is broken up into parts separated by opening and closing curly braces ({ and }). Everything between curly braces is considered a block and exists more or less independently of everything outside of the braces. Blocks aren’t important just from a logical sense—they are required as part of the syntax of the Java language. Without any braces, the compiler would have trouble determining where one section of code ends and the next section begins. From a purely aesthetic viewpoint, it would be very difficult for someone else reading your code to understand what was going on without the braces. For that matter, it wouldn’t be very easy for you to understand your own code without the braces.

    Braces are used to group related statements together. You can think of everything between matching braces as being executed as one statement. In fact, from an outer block, that’s exactly what an inner block appears like: a single statement. But what’s an outer block? Glad you asked, because it brings up another important point: Blocks can be hierarchical. One block can contain one or more nested subblocks.

    It is standard Java programming style to identify different blocks with indentation. Every time you enter a new block you should indent your source code by a number of spaces, preferably two. When you leave a block you should move back, or deindent, two spaces. This is a fairly established convention in many programming languages. However, it is just a style and is not technically part of the language. The compiler would produce identical output even if you didn’t indent anything. Indentation is used for the programmer, not the compiler; it simply makes the code easier to follow and understand. Following is an example of the proper indentation of blocks in Java:

    for (int i = 0; i < 5; i++) { if (i < 3) { System.out.println(i); }}Following is the same code without any block indentations:

    for (int i = 0; i < 5; i++) {if (i < 3) {System.out.println(i);}}The first code listing clearly shows the breakdown of program flow through the use of indentation; it is obvious that the if statement is nested within the for loop. The second code listing, on the other hand, provides no visual cues as to the relationship between the blocks of code. Don’t worry if you don’t know anything about if statements and for loops; you’ll learn plenty about them in the next chapter, “Expressions, Operators, and Control Structures.”

    The concept of scope is tightly linked to blocks and is very important when working with variables in Java. Scope refers to how sections of a program (blocks) affect the lifetime of variables. Every variable declared in a program has an associated scope, meaning that the variable only is used in that particular part of the program.

    Scope is determined by blocks. To better understand blocks, take a look again at the HelloWorld class in Listing 12.1. The HelloWorld class is composed of two blocks. The outer block of the program is the block defining the HelloWorld class:

    class HelloWorld {...}Class blocks are very important in Java. Almost everything of interest is either a class itself or belongs to a class. For example, methods are defined inside the classes they belong to. Both syntactically and logically, everything in Java takes place inside a class. Getting back to HelloWorld, the inner block defines the code within the main method as follows:

    public static void main (String args[]) {... }The inner block is considered to be nested within the outer block of the program. Any variables defined in the inner block are local to that block and are not visible to the outer block; the scope of the variables is defined as the inner block.

    To get an even better idea behind the usage of scope and blocks, take a look at the HowdyWorld class in Listing 12.2.

    • Listing 12.2. The HowdyWorld class.
    class HowdyWorld { public static void main (String args[]) { int i; printMessage(); } public static void printMessage () { int j; System.out.println(“Howdy, World!”); }}The HowdyWorld class contains two methods: main and printMessage. main should be familiar to you from the HelloWorld class, except in this case it declares an integer variable i and calls the printMessage method. printMessage is a new method that declares an integer variable j and prints the message “Howdy, World!” to the standard output stream, much like the main method did in HelloWorld.

    You’ve probably figured out already that HowdyWorld results in basically the same output as HelloWorld, because the call to printMessage results in a single text message being displayed. What you might not see right off is the scope of the integers defined in each method. The integer i defined in main has a scope limited to the body of the main method. The body of main is defined by the curly braces around the method (the method block). Similarly, the integer j has a scope limited to the body of the printMessage method. The importance of the scope of these two variables is that the variables aren’t visible beyond their respective scopes; the HowdyWorld class block knows nothing about the two integers. Furthermore, main doesn’t know anything about j, and printMessage knows nothing about i.

    Scope becomes more important when you start nesting blocks of code within other blocks. The GoodbyeWorld class shown in Listing 12.3 is a good example of variables nested within different scopes.

    • Listing 12.3. The GoodbyeWorld class.
    class GoodbyeWorld { public static void main (String args[]) { int i, j; System.out.println(“Goodbye, World!”); for (i = 0; i < 5; i++) { int k; System.out.println(“Bye!”); } }}The integers i and j have scopes within the main method body. The integer k, however, has a scope limited to the for loop block. Because k’s scope is limited to the for loop block, it cannot be seen outside of that block. On the other hand, i and j still can be seen within the for loop block. What this means is that scoping has a top-down hierarchical effect—variables defined in outer scopes still can be seen and used within nested scopes, but variables defined in nested scopes are limited to those scopes. Incidentally, don’t worry if you aren’t familiar with for loops, you’ll learn all about them in the next chapter, “Expressions, Operators, and Control Structures.”

    For more reasons than visibility, it is important to pay attention to the scope of variables when you declare them. Along with determining the visibility of variables, the scope also determines the lifetime of variables. This means that variables actually are destroyed when program execution leaves their scope. Looking at the GoodbyeWorld example again, storage for the integers i and j is allocated when program execution enters the main method. When the for loop block is entered, storage for the integer k is allocated. When program execution leaves the for loop block, the memory for k is freed and the variable destroyed. Similarly, when program execution leaves main, all of the variables in its scope are freed and destroyed (i and j). The concept of variable lifetime and scope becomes even more important when you start dealing with classes. You’ll get a good dose of this in Chapter 14, “Classes, Packages, and Interfaces.”

    Arrays

    An array is a construct that provides for the storage of a list of items of the same type. Array items can be of either a simple or composite data type. Arrays also can be multidimensional. Java arrays are declared with square brackets ([]). The following are a few examples of arrays in Java:

    int numbers[];char[] letters;long grid[][];If you are familiar with arrays in another language, you might be puzzled by the absence of a number between the square brackets specifying the number of items in the array. Java doesn’t allow you to specify the size of an empty array when declaring the array. You always must explicitly set the size of the array with the new operator or by assigning a list of items to the array on creation. The new operator is covered in the next chapter, “Expressions, Operators, and Control Structures.”

    NOTEIt might seem like a hassle to always have to explicitly set the size of an array with the new operator. The reason for doing this is because Java doesn’t have pointers like C or C++ and therefore doesn’t allow you to just point anywhere in an array and create new items. By handling memory management this way, the bounds checking problems common with C and C++ have been avoided in the Java language.

    Another strange thing you might notice about Java arrays is the optional placement of the square brackets in the array declaration. You are allowed to place the square brackets either after the variable type or after the identifier.

    The following are a couple of examples of arrays that have been declared and set to a specific size by using the new operator or by assigning a list of items in the array declaration:

    char alphabet[] = new char[26];int primes = {7, 11, 13};More complex structures for storing lists of items, such as stacks and hashtables, are also supported by Java. Unlike arrays, these structures are implemented in Java as classes. You’ll get a crash course in some of these other storage mechanisms in Chapter 19, “The Utilities Package.”

    Strings

    In Java, strings are handled by a special class called String. Even literal strings are managed internally by an instantiation of a String class. An instantiation of a class is simply an object that has been created based on the class description. This method of handling strings is very different from languages like C and C++, where strings are represented simply as an array of characters. The following are a few strings declared using the Java String class:

    String message;String name = “Mr. Blonde”;At this point it’s not that important to know the String class inside and out. You’ll learn all the gory details of the String class in Chapter 18, “The Language Package.”

    Summary

    In this chapter, you have taken a look at the core components of the Java language. It is hoped that you now have a better insight about why Java has become popular in such a relatively short time. With vast improvements over the weaknesses of the C and C++ languages—arguably the industry language standards—Java will no doubt become more important in the near future. The language elements covered in this chapter are just the tip of the iceberg when it comes to the benefits of programming in Java.

    Now that you are armed with the fundamentals of the Java language, it is hoped that you are ready to press onward and learn more about the Java language. The next chapter, “Expressions, Operators, and Control Structures,94" covers exactly what its title suggests. In it you will learn how to work with and manipulate much of the information you learned about in this chapter. In doing so, you will be able to start writing programs that do a little more than display cute messages on the screen.

  4. #34
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    Chapter 13

    Expressions, operators, and control structures

    In the previous chapter you learned about the basic components of a Java program. This chapter focuses on how to use these components to do more useful things. Data types are interesting, but without expressions and operators you can’t do much with them. Even expressions and operators alone are somewhat limited in what they can do. Throw in control structures and you have the ability to do some interesting things.

    This chapter covers all of these issues and pulls together many of the missing pieces of the Java programming puzzle you’ve begun to assemble. You’ll not only expand your knowledge of the Java language a great deal, but also learn what it takes to write some more interesting programs.

    Expressions and Operators

    Once you have created variables, you typically want to do something with them. Operators enable you to perform an evaluation or computation on a data object or objects. Operators applied to variables and literals form expressions. An expression can be thought of as a programmatic equation. More formally, an expression is a sequence of one or more data objects (operands) and zero or more operators that produce a result. An example of an expression follows:

    x = y / 3;In this expression, x and y are variables, 3 is a literal, and = and / are operators. This expression states that the y variable is divided by 3 using the division operator (/), and the result is stored in x using the assignment operator (=). Notice that the expression was described from right to left. This is the standard technique for breaking down and understanding expressions in Java, as well as most other programming languages. This right-to-left evaluation of expressions isn’t just a technique for your own understanding of expressions—it’s how the compiler itself analyzes expressions to generate code.

    Operator Precedence

    Even with the compiler analyzing expressions right to left, there still are many times when the result of an expression would be indeterminate without any other rules. The following expression illustrates the problem:

    x = 2 * 5 + 12 / 4Strictly using the right-to-left evaluation of the expression, the division operation 12 / 4 is carried out first, which leaves a result of 3. The addition operation 5 + 3 is then performed, which gives you a result of 8. The multiplication operation 2 * 8 is then performed, which gives you a result of 16. Finally, the assignment operation x = 16 is handled, in which case the number 16 is assigned to the variable x.

    If you have some experience with operator precedence from another language, you might already be questioning the evaluation of this expression, and for good reason—it’s wrong! The problem is that using a simple right-to-left evaluation of expressions can yield inconsistentresults, depending on the order of the operators. The solution to this problem lies in operator precedence, which determines the order in which operators are evaluated. Every Java operator has an associated precedence. Following is a listing of all the Java operators from highest to lowest precedence:

    . [] ()

    ++ -- ! ~

    * / %

    + -

    << >> >>>

    < > <= >=

    == !=

    &

    ^

    &&

    ||

    ?:

    =

    In this list of operators, all of the operators in a particular row have equal precedence. The precedence level of each row decreases from top to bottom. This means that the [] operator has a higher precedence than the * operator, but the same precedence as the () operator.

    Expression evaluation still moves from right to left, but only when dealing with operators that have the same precedence. Otherwise, operators with a higher precedence are evaluated before operators with a lower precedence. Knowing this, take a look at the same equation again:

    x = 2 * 5 + 12 / 4Before using the right-to-left evaluation of the expression, first look to see if any of the operators have differing precedence. Indeed they do! The multiplication (*) and division (/) operators both have the highest precedence, followed by the addition operator (+), and then theassignment operator (=). Because the multiplication and division operators share the same precedence, evaluate them from right to left. Doing this, you perform the division operation 12 / 4 first, resulting in 3. You then perform the multiplication operation 2 * 5, which results in 10. After performing these two operations, the expression looks like this:

    x = 10 + 3;Because the addition operator has a higher precedence than the assignment operator, you perform the addition 10 + 3 next, resulting in 13. Finally, the assignment operation x = 13 is processed, resulting in the number 13 being assigned to the variable x. As you can see, evaluating the expression using operator precedence yields a completely different result.

    Just to get the point across, take a look at another expression that uses parentheses for grouping purposes:

    x = 2 * (11 - 7);Without the grouping parentheses, you would perform the multiplication first and then the subtraction. However, referring back to the precedence list, the () operator comes before all other operators. So, the subtraction 11 - 7 is performed first, yielding 4 and the following expression:

    x = 2 * 4;The rest of the expression is easily resolved with a multiplication and an assignment to yield a result of 8 in the variable x.

    Integer Operators

    There are three types of operations that can be performed on integers: unary, binary, and relational. Unary operators act only on single integer numbers, and binary operators act on pairs of integer numbers. Both unary and binary integer operators return integer results. Relational operators, on the other hand, act on two integer numbers but return a Boolean result rather than an integer.

    Unary and binary integer operators typically return an int type. For all operations involving the types byte, short, and int, the result is always an int. The only exception to this rule is if one of the operands is a long, in which case the result of the operation also will be of type long.

    Unary

    Unary integer operators act on a single integer. Table 13.1 lists the unary integer operators.

    Table 13.1. The unary integer operators.

    DescriptionOperatorIncrement++.Decrement--Negation-Bitwise complement~

    The increment and decrement operators (++ and --) increase and decrease integer variables by one. Similar to their complements in C and C++, these operators can be used in either prefix or postfix form. A prefix operator takes effect prior to the evaluation of the expression it is in, and a postfix operator takes effect after the expression has been evaluated. Prefix unary operators are placed immediately before the variable and postfix unary operators are placed immediately following the variable. Following is an example of each type of operator:

    y = ++x;z = x--;In the first example, x is prefix incremented, which means that it is incremented before being assigned to y. In the second example, x is postfix decremented, which means that it is decremented after being assigned to z. In the latter case, z is assigned the value of x prior to x being decremented. Listing 13.1 contains the IncDec program, which uses both types of operators. Please note that the IncDec program is actually implemented in the Java class IncDec. This is a result of the object-oriented structure of Java, which requires programs to be implemented as classes. So, when you see a reference to a Java program, keep in mind that it is really referring to a Java class.

    • Listing 13.1. The IncDec class.
    class IncDec { public static void main (String args[]) { int x = 8, y = 13; System.out.println(“x = “ + x); System.out.println(“y = “ + y); System.out.println(“++x = “ + ++x); System.out.println(“y++ = “ + y++); System.out.println(“x = “ + x); System.out.println(“y = “ + y); }}The IncDec program produces the following results:

    x = 8y = 13++x = 9y++ = 13x = 9y = 14The negation unary integer operator (-) is used to change the sign of an integer value. This operator is as simple as it sounds, as indicated by the following example:

    x = 8;y = -x;In this example, x is assigned the literal value 8 and then is negated and assigned to y. The resulting value of y is -8. To see this code in a real Java program, check out the Negation program in Listing 13.2.

    • Listing 13.2. The Negation class.
    class Negation { public static void main (String args[]) { int x = 8; System.out.println(“x = “ + x); int y = -x; System.out.println(“y = “ + y); }}The last Java unary integer operator is the bitwise complement operator (~), which performs a bitwise negation of an integer value. Bitwise negation means that each bit in the number is toggled. In other words, all of the binary zeros become ones and all the binary ones become zeros. Take a look at an example very similar to the one for the negation operator:

    x = 8;y = ~x;In this example x is assigned the literal value 8 again, but it is bitwise complemented before being assigned to y. What does this mean? Well, without getting into the details of how integers are stored in memory, it means that all of the bits of the variable x are flipped, yielding a decimal result of -9. This result has to do with the fact that negative numbers are stored in memory using a method known as two’s complement (see the following note). If you’re having trouble believing any of this, try it yourself with the BitwiseComplement program shown in Listing 13.3.

    NOTEInteger numbers are stored in memory as a series of binary bits that can each have a value of 0 or 1. A number is considered negative if the highest-order bit in the number is set to 1. Because a bitwise complement flips all the bits in a number, including the high-order bit, the sign of a number is reversed.

    • Listing 13.3. The BitwiseComplement class.
    class BitwiseComplement { public static void main (String args[]) { int x = 8; System.out.println(“x = “ + x); int y = ~x; System.out.println(“y = “ + y); }}

  5. #35
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    Binary

    Binary integer operators act on pairs of integers. Table 13.2 lists the binary integer operators.

    Table 13.2. The binary integer operators.

    DescriptionOperatorAddition+Subtraction-Multiplication*Division /Modulus%Bitwise AND&Bitwise OR|Bitwise XOR^Left Shift<<Right Shift >>Zero-Fill Right Shift >>>

    The addition, subtraction, multiplication, and division operators (+, -, *, and /) all do what you would expect them to. An important thing to note is how the division operator works; because you are dealing with integer operands, the division operator returns an integer divisor. In cases where the division results in a remainder, the modulus operator (%) can be used to get the remainder value. Listing 13.4 contains the Arithmetic program, which shows how the basic binary integer arithmetic operators work.

    • Listing 13.4. The Arithmetic class.
    class Arithmetic { public static void main (String args[]) { int x = 17, y = 5; System.out.println(“x = “ + x); System.out.println(“y = “ + y); System.out.println(“x + y = “ + (x + y)); System.out.println(“x - y = “ + (x - y)); System.out.println(“x * y = “ + (x * y)); System.out.println(“x / y = “ + (x / y)); System.out.println(“x % y = “ + (x % y)); }}The results of running the Arithmetic program follow:

    x = 17y = 5x + y = 22x - y = 12x * y = 85x / y = 3x % y = 2These results shouldn’t surprise you too much. Just notice that the division operation x / y, which boils down to 17 / 5, yields the result 3. Also notice that the modulus operation x % y, which is resolved down to 17 % 5, ends up with a result of 2, which is the remainder of the integer division.

    Mathematically, a division by zero results in an infinite result. Because representing infinite numbers is a big problem for computers, division or modulus operations by zero result in an error. To be more specific, a runtime exception is thrown. You’ll learn a lot more about exceptions in Chapter 16, “Exception Handling.”

    The bitwise AND, OR, and XOR operators (&, |, and ^) all act on the individual bits of an integer. These operators sometimes are useful when an integer is being used as a bit field. An example of this is when an integer is used to represent a group of binary flags. An int is capable of representing up to 32 different flags, because it is stored in 32 bits. Listing 13.5 contains the program Bitwise, which shows how to use the binary bitwise integer operators.

    • Listing 13.5. The Bitwise class.
    class Bitwise { public static void main (String args[]) { int x = 5, y = 6; System.out.println(“x = “ + x); System.out.println(“y = “ + y); System.out.println(“x & y = “ + (x & y)); System.out.println(“x | y = “ + (x | y)); System.out.println(“x ^ y = “ + (x ^ y)); }}The output of running Bitwise follows:

    x = 5y = 6x & y = 4x | y = 7x ^ y = 3To understand this output, you must first understand the binary equivalents of each decimal number. In Bitwise, the variables x and y are set to 5 and 6, which correspond to the binary numbers 0101 and 0110. The bitwise AND operation compares each bit of each number to see if they are the same. It then sets the resulting bit to 1 if both bits being compared are 1, and 0 otherwise. The result of the bitwise AND operation on these two numbers is 0100 in binary, or decimal 4. The same logic is used for both of the other operators, except that the rules for comparing the bits are different. The bitwise OR operator sets the resulting bit to 1 if either of the bits being compared is 1. For these numbers, the result is 0111 binary, or 7 decimal. Finally, the bitwise XOR operator sets resulting bits to 1 if exactly one of the bits being compared is 1, and 0 otherwise. For these numbers, the result is 0011 binary, or 3 decimal.

    The left-shift, right-shift, and zero-fill-right-shift operators (<<, >>, and >>>) shift the individual bits of an integer by a specified integer amount. The following are some examples of how these operators are used:

    x << 3;y >> 7;z >>> 2;In the first example, the individual bits of the integer variable x are shifted to the left three places. In the second example, the bits of y are shifted to the right seven places. Finally, the third example shows z being shifted to the right two places, with zeros shifted into the two leftmost places. To see the shift operators in a real program, check out Shift in Listing 13.6.

    • Listing 13.6. The Shift class.
    class Shift { public static void main (String args[]) { int x = 7; System.out.println(“x = “ + x); System.out.println(“x >> 2 = “ + (x >> 2)); System.out.println(“x << 1 = “ + (x << 1)); System.out.println(“x >>> 1 = “ + (x >>> 1)); }}The output of Shift follows:

    x = 7x >> 2 = 1x << 1 = 14x >>> 1 = 3The number being shifted in this case is the decimal 7, which is represented in binary as 0111. The first right-shift operation shifts the bits two places to the right, resulting in the binary number 0001, or decimal 1. The next operation, a left shift, shifts the bits one place to the left, resulting in the binary number 1110, or decimal 14. Finally, the last operation is a zero-fill right shift, which shifts the bits 1 place to the right, resulting in the binary number 0011, or decimal 3. Pretty simple, huh? And you probably thought it was difficult working with integers at the bit level!

    Based on these examples, you may be wondering what the difference is between the right-shift (>>) and zero-fill-right-shift operators (>>>). The right-shift operator appears to shift zeros into the leftmost bits, just like the zero-fill-right-shift operator, right? Well, when dealing with positive numbers, there is no difference between the two operators; they both shift zeros into the upper bits of a number. The difference arises when you start shifting negative numbers. Remember that negative numbers have the high-order bit set to 1. The right-shift operator preserves the high-order bit and effectively shifts the lower 31 bits to the right. This behavior yields results for negative numbers similar to those for positive numbers. That is, -8 shifted right by one will result in -4. The zero-fill-right-shift operator, on the other hand, shifts zeros into all the upper bits, including the high-order bit. When this shifting is applied to negative numbers, the high-order bit becomes 0 and the number becomes positive.

    Relational

  6. #36
    التسجيل
    03-08-2004
    الدولة
    تركيا
    المشاركات
    3,755

    مشاركة: SAMS PUBLISHING " JAVA UNLEASHED " VOL 1

    The last group of integer operators is the relational operators, which all operate on integers but return a type boolean. Table 13.3 lists the relational integer operators.

    Table 13.3. The relational integer operators.

    DescriptionOperatorLess Than <Greater Than>Less Than Or Equal To<=Greater Than Or Equal To>=Equal To==Not Equal To!=

    These operators all perform comparisons between integers. Listing 13.7 contains the Relational program, which demonstrates the use of the relational operators with integers.

    • Listing 13.7. The Relational class.
    class Relational { public static void main (String args[]) { int x = 7, y = 11, z = 11; System.out.println(“x = “ + x); System.out.println(“y = “ + y); System.out.println(“z = “ + z); System.out.println(“x < y = “ + (x < y)); System.out.println(“x > z = “ + (x > z)); System.out.println(“y <= z = “ + (y <= z)); System.out.println(“x >= y = “ + (x >= y)); System.out.println(“y == z = “ + (y == z)); System.out.println(“x != y = “ + (x != z)); }}The output of running Relational follows:

    x = 7y = 11z = 11x < y = truex > z = falsey <= z = truex >= y = falsey == z = truex != y = trueAs you can see, the println method is smart enough to print Boolean results correctly as true and false.

    Floating-Point Operators

    Similar to integer operators, there are three types of operations that can be performed onfloating-point numbers: unary, binary, and relational. Unary operators act only on single floating-point numbers, and binary operators act on pairs of floating-point numbers. Both unary and binary floating-point operators return floating-point results. Relational operators, however, act on two floating-point numbers but return a Boolean result.

    Unary and binary floating-point operators return a float type if both operands are of type float. If one or both of the operands is of type double, however, the result of the operation is of type double.

    Unary

    The unary floating point operators act on a single floating-point number. Table 13.4 lists the unary floating-point operators.

    Table 13.4. The unary floating-point operators.

    DescriptionOperator

    Increment++Decrement--





    As you can see, the only two unary floating point operators are the increment and decrement operators. These two operators respectively add and subtract 1.0 from their floating-point operand.

    Binary

    The binary floating-point operators act on a pair of floating-point numbers. Table 13.5 lists the binary floating-point operators.

    Table 13.5. The binary floating-point operators.

    DescriptionOperator

    Addition+Subtraction-Multiplication*Division/Modulus%





    The binary floating-point operators consist of the four traditional binary operations (+, -, *, ), along with the modulus operator (%). You might be wondering how the modulus operator fits in here, considering that its usage as an integer operator relied on an integer division. If you recall, the integer modulus operator returned the remainder of an integer division of the two operands. But a floating-point division never results in a remainder, so what does a floating-point modulus do? The floating-point modulus operator returns the floating-point equivalent of an integer division. What this means is that the division is carried out with both floating-point operands, but the resulting divisor is treated as an integer, resulting in a floating-point remainder. Listing 13.8 contains the FloatMath program, which shows how the floating-point modulus operator works along with the other binary floating-point operators.

    • Listing 13.8. The FloatMath class.
    class FloatMath { public static void main (String args[]) { float x = 23.5F, y = 7.3F; System.out.println(“x = “ + x); System.out.println(“y = “ + y); System.out.println(“x + y = “ + (x + y)); System.out.println(“x - y = “ + (x - y)); System.out.println(“x * y = “ + (x * y)); System.out.println(“x / y = “ + (x / y)); System.out.println(“x % y = “ + (x % y)); }}The output of FloatMath follows:

    x = 23.5y = 7.3x + y = 30.8x - y = 16.2x * y = 171.55x / y = 3.21918x % y = 1.6The first four operations no doubt performed as you expected, taking the two floating-point operands and yielding a floating-point result. The final modulus operation determined that 7.3 divides into 23.5 an integral amount of 3 times, leaving a remaining result of 1.6.

    Relational

    The relational floating-point operators compare two floating-point operands, leaving a Boolean result. The floating-point relational operators are the same as the integer relational operators listed in Table 13.3, except that they work on floating-point numbers.

    Boolean Operators

    Boolean operators act on Boolean types and return a Boolean result. The Boolean operators are listed in Table 13.6.

    Table 13.6. The Boolean operators.

    DescriptionOperator

    Evaluation AND&Evaluation OR|Evaluation XOR^Logical AND &&Logical OR D="I228" NAME="I228"> ||Negation!Equal To==Not Equal To !=Conditional?:





    The evaluation operators (&, |, and ^) evaluate both sides of an expression before determining the result. The logical operators (&& and ||) avoid the right-side evaluation of the expression if it is not needed. To better understand the difference between these operators, take a look at the following two expressions:

    boolean result = isValid & (Count > 10);boolean result = isValid && (Count > 10);The first expression uses the evaluation AND operator to make an assignment. In this case, both sides of the expression always are evaluated, regardless of the values of the variables involved. In the second example, the logical AND operator (&&) is used. This time, the isValid Boolean value is first checked. If it is false, the right side of the expression is ignored and the assignment is made. This is more efficient because a false value on the left side of the expression provides enough information to determine the false outcome.

    Although the logical operators are more efficient, there still may be times when you want to use the evaluation operators to ensure that the entire expression is evaluated. The following code shows how the evaluation AND operator is necessary for the complete evaluation of an expression:

    while ((++x < 10) && (++y < 15)) { System.out.println(x); System.out.println(y);}In this example, the second expression (++y > 15) is evaluated after the last pass through the loop because of the evaluation AND operator. If the logical AND operator had been used, the second expression would not have been evaluated and y would not have been incremented after the last time around.

    The Boolean operators negation, equal-to, and not-equal-to (!, ==, and !=) perform exactly as you might expect. The negation operator toggles the value of a Boolean from false to true or from true to false, depending on the original value. The equal-to operator simply determines whether two Boolean values are equal (both true or both false). Similarly, the not-equal-to operator determines whether two Boolean operands are unequal.

    The conditional Boolean operator (? is the most unique of the Boolean operators, and is worth a closer look. This operator also is known as the ternary operator because it takes three items: a condition and two expressions. The syntax for the conditional operator follows:

    Condition ? Expression1 : Expression2The Condition, which itself is a Boolean, is first evaluated to determine whether it is true or false. If Condition evaluates into a true result, Expression1 is evaluated. If Condition ends up being false, Expression2 is evaluated. To get a better feel for the conditional operator, check out the Conditional program in Listing 13.9.

    • Listing 13.9. The Conditional class.
    class Conditional { public static void main (String args[]) { int x = 0; boolean isEven = false; System.out.println(“x = “ + x); x = isEven ? 4 : 7; System.out.println(“x = “ + x); }}The results of the Conditional program follow:

    x = 0x = 7The integer variable x is first assigned a value of 0. The Boolean variable isEven is assigned a value of false. Using the conditional operator, the value of isEven is checked. Because it is false, the second expression of the conditional is used, which results in the value 7 being assigned to x.

    String Operators

    Along with integers, floating-point numbers, and Booleans, strings also can be manipulated with operators. Actually, there is only one string operator: the concatenation operator (+). The concatenation operator for strings works very similarly to the addition operator for numbers—it adds strings together. The concatenation operator is demonstrated in the Concatenation program shown in Listing 13.10.

    • Listing 13.10. The Concatenation class.
    class Concatenation { public static void main (String args[]) { String firstHalf = “What “ + “did “; String secondHalf = “you “ + “say?”; System.out.println(firstHalf + secondHalf); }}The output of Concatenation follows:

    What did you say?In the Concatenation program, literal strings are concatenated to make assignments to the two string variables, firstHalf and secondHalf, upon creation. The two string variables are then concatenated within the call to the println method

صفحة 3 من 3 الأولىالأولى 123

ضوابط المشاركة

  • لا تستطيع إضافة مواضيع جديدة
  • لا تستطيع الرد على المواضيع
  • لا تستطيع إرفاق ملفات
  • لا تستطيع تعديل مشاركاتك
  •