【问题标题】:Why not just declare Object class for all objects?为什么不为所有对象声明 Object 类?
【发布时间】:2015-03-10 05:20:16
【问题描述】:

我刚刚看到这个关于 Java 的精彩教程视频,我发现 Object 类是所有幕后类的超类。这样就很容易解决arraylist中存在多种数据类型的问题,只需在处理列表本身时声明Object类即可。

我的问题是: 为什么不为所有对象声明Object object = new SubObjectClass();

这是因为我还没有遇到过某种性能低效或内存问题吗?我发现了另一个问题,但我没有看到有人解释为什么不只是有 Object 类声明?

我明白它为什么在那里。如果这是一个基本问题,我深表歉意。

【问题讨论】:

  • 试一试,看看做完后访问类的属性是多么容易......
  • JavaScript 或多或少按照你描述的方式做事;您对所有变量使用var,并且您没有指定类型名称。这有优点,但也有缺点:(1)它可以很容易地将变量分配给错误类型的对象,而在 Java 中,强类型可以让您在编译时捕获许多错误; (2) 每当你调用一个方法时,程序必须进行搜索以找出该对象是否有一个具有该名称的方法,而我认为在 Java 中它只是从数组中加载一个虚拟地址,这要快一些。

标签: java c# oop


【解决方案1】:

当然,您可以这样做,但是每次尝试通过变量访问成员时都必须进行类型转换。该类型转换检查需要时间来执行,因为它需要确保在对象的类与类型转换约束不匹配时引发异常。

通过使用适当类型的变量,大部分内容被转移到编译时,允许(几乎)未经检查的运行时访问成员,只要对象不是null

【讨论】:

    【解决方案2】:

    你可以像你说的那样声明对象列表:

    List<Object> list = new ArrayList<Object>();
    

    这将是“对象”的通用列表,可以存储任何类型的对象。

    但是当我们尝试从这样的列表中检索项目时会出现问题,我们将 需要将检索到的对象转换为特定的对象类型。 为了进一步处理。

    我们不确定哪个对象会从列表中删除。

    【讨论】:

      【解决方案3】:

      不使用它的一个原因可能是比较或将对象分配给其他对象时出现问题。

      例如:

      Object obj = new SubObjectclass();
      SubObjectClass subobj = obj;// This will throw error. 
      SubObjectClass subobj = (SubObjectClass)obj;//This will work.
      

      【讨论】:

        【解决方案4】:

        这样做还有一个问题是你不能用超类的对象访问子类的变量或方法。它只能访问超类的变量或方法

        这里是例子

        import java.util.*;
        import java.lang.*;
        import java.io.*;
        
        /* Name of the class has to be "Main" only if the class is public. */
        class Ideone
        {
        public static void main (String[] args) throws java.lang.Exception
        {
            Object obj= new subclass();
            System.out.println(obj.i);
            System.out.println(obj.abc());
        
            // your code goes here
        }
        }
        
        class subclass
        {
        int a;
        public int abc(){
            return 1;
        }
        }
        

        这是我尝试编译时收到的错误:

        Main.java:13: error: cannot find symbol
            System.out.println(obj.i);
                                  ^
        symbol:   variable i
        location: variable obj of type Object
        Main.java:14: error: cannot find symbol
            System.out.println(obj.abc());
                                  ^
        symbol:   method abc()
        location: variable obj of type Object
        2 errors
        

        【讨论】:

          【解决方案5】:

          Java 中的类型擦除会对性能造成巨大影响,因为所有内容都必须装箱和拆箱。如前所述,您也可以在 C# 中创建对象集合,但应避免使用。

          What are the differences between Generics in C# and Java... and Templates in C++?

          http://www.jprl.com/Blog/archive/development/2007/Aug-31.html

          【讨论】:

          • 我看不出这个答案与问题有什么关系。
          • 首先,这个问题可能是由提到仿制药的视频提出的,但问题与仿制药无关。其次,类型擦除是所有泛型的一个特性,所以你无法避免它,我认为它根本不会导致性能下降。您可能正在考虑原始类型,其中您说 List list = ... 没有类型参数。而且原始类型与问题无关,因为OP引用了List&lt;Object&gt;,这不是原始类型。
          • 类型擦除在 Java 中发生,但在 C# 中不发生。这就是 Java 泛型性能受到很大影响的原因。
          • 好的,我知道它可能是真的,因为需要在 Java 中进行的一些运行时检查可能不会在 C# 中。我没有研究过字节码。无论如何,它离最初的问题还很遥远;他在问为什么不将 Java 中的每个对象都声明为 Object 类型,而我们在这里讨论为什么 C# 中的泛型比 Java 中的更快。
          • 这个问题也用 C# 标记,他提到在数组列表中有多种数据类型。在 Java 中声明 ArrayList 只是带走了类型安全性,因为在运行时类型无论如何都会被删除。在 C# 中,从强类型列表到 引入了性能损失(强制转换和值类型也装箱/拆箱)。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-12-18
          • 1970-01-01
          • 1970-01-01
          • 2023-03-21
          • 2022-11-17
          • 1970-01-01
          • 2021-06-10
          相关资源
          最近更新 更多