java.lang.Object类的行为

时间:2010-11-03 01:14:28

标签: java object

试图理解java.lang.Object类的行为。

public class TypeCheck{
    static void printMethod(Object obj)
    {
        System.out.println(obj);
    }

    public static void main(String[] args)
    {
        Object obj       = new Object();
        Integer intObj   = new Integer(12);
        String stringObj = new String("Hello");

        printMethod(obj); //---> java.lang.Object@78b5f53a
        printMethod(intObj); //---> 12
        printMethod(stringObj); // ---> Hello
    }
}

我的问题是:

  1. 我们什么时候应该使用Object类?
  2. 但是,当我只传递printMethod(intObj)并在printMethod(Object obj)时,我会添加System.out.println(obj+1)它不起作用。如果obj认识到它是一个整数,为什么我不能对它进行操作呢? 例外:TypeCheck.java:5: operator + cannot be applied to java.lang.Object,int System.out.println(obj+1);
  3. 现在,如果我这样做:

    public class TypeCheck
    {
        static void printMethod(Object obj)
        {
            System.out.println(obj.getClass().getName());
        }
        public static void main(String[] args)
        {
            int i = 666;
            printMethod(i);
        }
    }
    

    它返回java.lang.Integer,但它被定义为int(原始类型)。为什么Java在传递给Object时将原始类型转换为它的包装类。

4 个答案:

答案 0 :(得分:3)

  1. 几乎没有。您应该使用特定的对象。
  2. 这应该有效。见下文
  3. 因为基元(即int)不是对象。因此,需要将对象(盒装)作为一个对象传递。
  4. 编辑以回答问题编辑:

    (第2号)
    printMethod内,obj的类型不是int,而是Object。你不能添加对象!您需要将其强制转换回Integerint,然后才能对其执行此类操作。如果您将+的实例传递给TypeCheckTypeCheck.printMethod会怎么做?

答案 1 :(得分:1)

  1. 您很少需要使用Object本身。 Object是一个占位符,包含toString(),hashCode()等内容的默认实现。但是,您不需要显式扩展它来获取它们 - 每个类都会自动继承它们。

  2. Java是一种静态类型语言,这意味着在编译时进行类型检查以确保所有参数都是正确的类型,方法存在于它们被调用的对象的(声明的)类型上, 等等。编译器不知道您可以将Integer传递给printMethod,而当{i}是字符串或裸对象时obj+1没有意义。你可以将它强制转换为整数,但当你传入非整数时,这当然会中断(ClassCastException)。

  3. 原始类型不是Java中的对象。当Java编译器看到使用需要对象的基本类型的代码时:

    int i = 5;
    printMethod(i);
    

    它编译好像是:

    int i = 5;
    printMethod(new Integer(i));
    

    这被称为autoboxing,并在Java 5中引入,以便原始类型可以存储在collections中。

    添加(如第二个问题)就像:

    // ... assume obj has been cast to an Integer ...
    System.out.println(obj.intValue() + 1);
    

    obj实际上是一个Object时,这当然没有意义,因为它不会有一个整数值开始!

答案 2 :(得分:0)

问题1 当您拥有不同类的不同对象的列表/数组时,您需要访问每个对象。 (我知道这很糟糕,我们应该使用Generics,但这不是重点)Object是所有类的超类,你可以用它来引用任何其他对象。

问题2 在执行添加操作之前将其强制转换为Integer,因为添加操作属于Integer类而不是Object类。

打印对象时,将调用toString()方法。 Object类中toString()的实现返回指针,Integer中toString()的实现返回整数的值。根据对象的类型,虽然实例是相同的,但是将调用相应的toString()方法。

问题3 您必须了解的另一个概念是AutoBoxing。 Java会自动将您的原始int转换为Integer。

答案 3 :(得分:0)

  1. 我相信你很少直接使用Object。我的意思是你几乎不会实例化它。 Object的目的是成为所有其他对象的公共父级(所有类都继承自Object类)。因此,Object将定义Java中所有对象将具有的方法,如toString。有时你会使用一个Object指针来保存一个未知身份的类,但是大多数时候,你可以找到一个更接近父类的候选类,这个候选类可以由这个指针保存。

  2. 当您传递intObj(它是一个Integer,但可以作为Object传递,因为Integer继承自Object)时,该方法不会将其识别为Integer。如果它打印一个数字,那是因为Integer类中的toString方法被覆盖以打印它所代表的值,而不是类的名称及其地址。也是这样看的...你不能在printMethod中对Integer进行操作,因为printMethod不知道它是原始Object,Integer还是其他任何东西。如果将Object转换为整数,则应取消装箱,操作将成功。

  3. 这叫做自动装箱。拳击是将一个原语放在一个基本只保留原语的对象中。因此,当您将int传递给等待对象的方法时,将其装入Integer中的int然后传递给方法。