`
leonzhx
  • 浏览: 794023 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Chapter 3. Operators -- Thinking in Java

阅读更多

1) An operator takes one or more arguments and produces a new value. The arguments are in a different form than ordinary method calls, but the effect is the same. All operators produce a value from their operands. In addition, some operators change the value of an operand. This is called a side effect. The most common use for operators that modify their operands is to generate the side effect, but you should keep in mind that the value produced is available for your use, just as in operators without side effects.

 

2) Almost all operators work only with primitives. The exceptions are ‘=', '==' and ‘!=', which work with all objects (and are a point of confusion for objects). In addition, the String class supports ‘+' and ‘+='.

 

3) Operator precedence defines how an expression evaluates when several operators are present. Java has specific rules that determine the order of evaluation. The easiest one to remember is that multiplication and division happen before addition and subtraction. When the compiler sees a String followed by a ‘+' followed by a non-String, it attempts to convert the non-String into a String.

 

4) Assignment is performed with the operator =. It means “Take the value of the right-hand side (often called the rvalue) and copy it into the left-hand side (often called the lvalue)”. An rvalue is any constant, variable, or expression that produces a value, but an lvalue must be a distinct, named variable. (That is, there must be a physical space to store the value.)

 

5) when you assign primitives, you copy the contents from one place to another. When you assign objects, however, things change. Whenever you manipulate an object, what you’re manipulating is the reference, so when you assign “from one object to another,” you’re actually copying a reference from one place to another. This phenomenon is often called aliasing, and it’s a fundamental way that Java works with objects. Aliasing will also occur when you pass an object into a method. (Reference instead of Object is passed)

 

6) If you create a Random object with no arguments, Java uses the current time as a seed for the random number generator, and will thus produce different output for each execution of the program. By providing a seed (an initialization value for the random number generator that will always produce the same sequence for a particular seed value) when creating the Random object, the same random numbers will be generated each time the program is executed.

 

7) The decrement operator is -- and means “decrease by one unit.” The increment operator is ++ and means “increase by one unit.” Increment and decrement operators not only modify the variable, but also produce the value of the variable as a result. There are two versions of each type of operator, often called the prefix and postfix versions. Pre-increment means the ++ operator appears before the variable, and post-increment means the ++ operator appears after the variable. Similarly, pre-decrement means the -- operator appears before the variable, and post-decrement means the -- operator appears after the variable. For pre-increment and pre-decrement , the operation is performed and the value is produced. For post-increment and post-decrement , the value is produced, then the operation is performed.

 

8) Relational operators generate a boolean result. They evaluate the relationship between the values of the operands. Equivalence and nonequivalence work with all primitives, but the other comparisons won’t work with type boolean.

 

9) The operators == and != compare object references. What if you want to compare the actual contents of an object for equivalence? You must use the special method equals( ) that exists for all objects. The default behavior of equals( ) is to compare references. So unless you override equals( ) in your new class you won’t get the desired behavior. Most of the Java library classes implement equals( ) so that it compares the contents of objects instead of their references.

 

10) You can apply AND(&&), OR(||), or NOT(!) to boolean values only. You can’t use a non-boolean as if it were a boolean in a logical expression.

 

11) The comparison of floating point numbers is very strict. A number that is the tiniest fraction different from another number is still “not equal.” A number that is the tiniest bit above zero is still nonzero.

 

12) When dealing with logical operators, you run into a phenomenon called “short-circuiting.” This means that the expression will be evaluated only until the truth or falsehood of the entire expression can be unambiguously determined. As a result, the latter parts of a logical expression might not be evaluated.

 

13) A trailing character after a literal value establishes its type. Uppercase or lowercase L means long (however, using a lowercase l is confusing because it can look like the number one). Uppercase or lowercase F means float. Uppercase or lowercase D means double.

 

14) Hexadecimal (base 16), which works with all the integral data types, is denoted by a leading 0x or 0X followed by 0-9 or a-f either in uppercase or lowercase. If you try to initialize a variable with a value bigger than it can hold (regardless of the numerical form of the value), the compiler will give you an error message. The max value of char is 0xffff while the max value of short is 0x7fff, because short is signed. Octal (base 8) is denoted by a leading zero in the number and digits from 0-7.

 

15) e would mean “ten to the power”, such as 4.7e-23. The compiler normally takes exponential numbers as doubles. Decimal literals are automatically taken as doubles.

 

16) The bitwise operators allow you to manipulate individual bits in an integral primitive data type. Bitwise operators perform Boolean algebra on the corresponding bits in the two arguments to produce the result.

 

17) XOR (^), produces a one in the output bit if one or the other input bit is a one, but not both. You can think it as determine whether two bits are not equal.

 

18) The boolean type is treated as a one-bit value, so it is somewhat different. You can perform a bitwise AND(&), OR(|), and XOR(^), but you can’t perform a bitwise NOT(~) (presumably to prevent confusion with the logical NOT). You cannot use booleans in shift expressions. And bitwise operations do not short circuit.

 

19) The shift operators also manipulate bits. They can be used solely with primitive, integral types. The left-shift operator (<<) produces the operand to the left of the operator after it has been shifted to the left by the number of bits specified to the right of the operator (inserting zeroes at the lower-order bits). The signed right-shift operator (>>) produces the operand to the left of the operator after it has been shifted to the right by the number of bits specified to the right of the operator. The signed right shift >> uses sign extension: If the value is positive, zeroes are inserted at the higher-order bits; if the value is negative, ones are inserted at the higher-order bits. Java has also added the unsigned right shift >>>, which uses zero extension: Regardless of the sign, zeroes are inserted at the higher-order bits.

 

20) If you shift a char, byte, or short, it will be promoted to int before the shift takes place, and the result will be an int. Only the five low-order bits of the right-hand side will be used. This prevents you from shifting more than the number of bits in an int. If you’re operating on a long, you’ll get a long result. Only the six low-order bits of the right-hand side will be used, so you can’t shift more than the number of bits in a long.

 

21) The ternary operator, also called the conditional operator, is unusual because it has three operands. It is truly an operator because it produces a value. The expression is of the form:  boolean-exp ? value0 : value1 . If boolean-exp evaluates to true, value0 is evaluated, and its result becomes the value produced by the operator. If boolean-exp is false, value1 is evaluated and its result becomes the value produced by the operator.

 

22) Java programmers cannot implement their own overloaded operators. If an expression begins with a String, then all operands that follow must be Strings. ( when primitives operate with Strings , they will be automatically converted to Strings. )

 

23) To perform a cast, put the desired data type inside parentheses to the left of any value. In Java, casting is safe, with the exception that when you perform a so-called narrowing conversion (that is, when you go from a data type that can hold more information to one that doesn’t hold as much), you run the risk of losing information. Here the compiler forces you to use a cast, in effect saying, “This can be a dangerous thing to do—if you want me to do it anyway you must make the cast explicit.” With a widening conversion an explicit cast is not needed, because the new type will more than hold the information from the old type so that no information is ever lost.

 

24) Java allows you to cast any primitive type to any other primitive type, except for boolean, which doesn’t allow any casting at all. Class (wrapper) types do not allow casting. To convert one to the other, there must be special methods.

 

25) Casting from a float or double to an integral value always truncates the number. If instead you want the result to be rounded, use the round( ) methods in java.lang.Math.

 

26) You’ll discover that if you perform any mathematical or bitwise operations on primitive data types that are smaller than an int (that is, char, byte, or short), those values will be promoted to int before performing the operations, and the resulting value will be of type int. So if you want to assign back into the smaller type, you must use a cast. (And, since you’re assigning back into a smaller type, you might be losing information.) In general, the largest data type in an expression is the one that determines the size of the result of that expression; if you multiply a float and a double, the result will be double; if you add an int and a long, the result will be long. Compound assignments (such as +=, *=) do not require casts for char, byte, or short, even though they are performing promotions that have the same results as the direct arithmetic operations. On the other hand, the lack of the cast certainly simplifies the code.

 

27) char is special , you cannot even assign short or byte to char without explicit cast.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics