2012年3月3日 星期六

instanceof


instanceof

Java提供了instanceof作為判別類別間繼承關係之用,如果要判定的物件為該類別或該類別的子類別則傳回true,否則傳回false。需特別注意的是,物件與類別間要有繼承關係,否則會有compile error,如錯誤狀況12

Java裡有個特別規定,就是任何陣列都繼承Object,所以類別陣列將繼承ObjectObject[],一般型別陣列則會繼承Object,但是一般型別不是物件,所以一般型別陣列不會繼承Object[]

範例程式:
class myBase1 { }

class myBase2 extends myBase1 { }

public class myInstanceof extends myBase2 {
  public static void main(String[] args) {
    myBase1 b1 = new myBase1();
    myBase2 b2 = new myBase2();
    myInstanceof i1 = new myInstanceof();

    if (i1 instanceof myBase1) {
      System.out.println("i1myBase1的後代");
    }
    else {
      System.out.println("i1不是myBase1的後代");
    }

    if (b1 instanceof myInstanceof) {
      System.out.println("b1myInstanceof的後代");
    }
    else {
      System.out.println("b1不是myInstanceof的後代");
    }

    if (null instanceof myBase1) {
      System.out.println("nullmyBase1的後代");
    }
    else {
      System.out.println("null不是myBase1的後代");
    }

    myBase2[] b2array = new myBase2[10];
    if (b2array instanceof Object) {
      System.out.println("b2arrayObject的後代");
    }
    else {
      System.out.println("b2array不是Object的後代");
    }

    if (b2array instanceof Object[]) {
      System.out.println("b2arrayObject[]的後代");
    }
    else {
      System.out.println("b2array不是Object[]的後代");
    }

    int[i = new int[10];
    if (i instanceof Object) {
      System.out.println("iObject的後代");
    }
    else {
      System.out.println("i不是Object的後代");
    }

    /*
    //錯誤狀況1
    if (i instanceof Object[]) {
      System.out.println("iObject[]的後代");
    }
    else {
      System.out.println("i不是Object[]的後代");
    }

    //錯誤狀況2
    Long lng = new Long(10);
    if (lng instanceof String) {
      System.out.println("lngString的後代");
    }
    else {
      System.out.println("lng不是String的後代");
    }
    */
  }
}


執行結果:
i1myBase1的後代
b1不是myInstanceof的後代
null不是myBase1的後代
b2arrayObject的後代
b2arrayObject[]的後代
iObject的後代

錯誤狀況1:
"myInstanceof.java": Error #: 365 : cannot compare int[] with java.lang.Object[]

錯誤狀況2:
"myInstanceof.java": Error #: 365 : cannot compare java.lang.Long with java.lang.String



Conditional Operator ? :






The conditional operator ? : uses the boolean value of one expression to decide which of two other expressions should be evaluated.


ConditionalExpression:
    ConditionalOrExpression
    ConditionalOrExpression ? Expression : ConditionalExpression

The conditional operator is syntactically right-associative (it groups right-to-left). Thus, a?b:c?d:e?f:g means the same as a?b:(c?d:(e?f:g)).
The conditional operator has three operand expressions. ? appears between the first and second expressions, and : appears between the second and third expressions.

The first expression must be of type boolean or Boolean, or a compile-time error occurs.
It is a compile-time error for either the second or the third operand expression to be an invocation of a void method.

In fact, by the grammar of expression statements (§14.8), it is not permitted for a conditional expression to appear in any context where an invocation of a void method could appear.
The type of a conditional expression is determined as follows:
  • If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression isT.

  • If one of the second and third operands is of the null type and the type of the other is a reference type, then the type of the conditional expression is that reference type.

  • Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:

    • If one of the operands is of type byte or Byte and the other is of type short or Short, then the type of the conditional expression is short.

    • If one of the operands is of type T where T is byteshort, or char, and the other operand is a constant expression (§15.28) of type int whose value is representable in type T, then the type of the conditional expression is T.

    • If one of the operands is of type T, where T is ByteShort, or Character, and the other operand is a constant expression (§15.28) of type int whose value is representable in the typeU which is the result of applying unboxing conversion to T, then the type of the conditional expression is U.

    • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

      Note that binary numeric promotion performs value set conversion (§5.1.13) and may perform unboxing conversion (§5.1.8).

  • Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2.
    The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1T2) (§15.12.2.7).
At run-time, the first operand expression of the conditional expression is evaluated first. If necessary, unboxing conversion is performed on the result.

The resulting boolean value is then used to choose either the second or the third operand expression:
  • If the value of the first operand is true, then the second operand expression is chosen.
  • If the value of the first operand is false, then the third operand expression is chosen.
The chosen operand expression is then evaluated and the resulting value is converted to the type of the conditional expression as determined by the rules stated above.

This conversion may include boxing (§5.1.7) or unboxing (§5.1.8) conversion.
The operand expression not chosen is not evaluated for that particular evaluation of the conditional expression.