我们投射物体或参考物吗?

时间:2015-07-30 10:44:23

标签: java

我的代码如下所示:

public class Hashtabledemo2 {

public static void main(String[] args) {

    Hashtable myCompay = new Hashtable(10);
    System.out.println("Add some employee objects to the hashtable..");

    Salary e1 = new Salary("Salary1", "Palo Alto, CA",
            1, 100000.00);
    Hourly e2 = new Hourly("Hourly2", "Cupertino, CA", 2, 100.00);

    Contractor e3 = new Contractor("Contractor3", "Milpitas, CA",3, 1000.00);

    myCompay.put(new Integer(e1.hashCode()), e1);
    myCompay.put(new Integer(e2.hashCode()), e2);
    myCompay.put(new Integer(e3.hashCode()), e2);

    System.out.println("The size of the hashtable is "+myCompay.size());

    int size = myCompay.size();

    for(int i=1;i<=size;i++){
    /* Note that the get() method of the  hashtable class returns a reference to the object
        that matches the given key:
         public Object get(Object key)
         */
        Employee current =  (Employee) myCompay.get(new Integer(i));



        if(current instanceof Hourly){ 
            ((Hourly) current).setHoursWorked(40);
        } else if(current instanceof Contractor){

            ((Contractor) current ).setDaysWorked(5);
        }
        current.computePay();
        current.mailCheck();

    }

薪水,小时和承包商都扩展了员工类。在我的理解中,我们将父项引用转换为子项,而不是反过来。我不明白这行代码如何工作:

Employee current =  (Employee) myCompay.get(new Integer(i));

这行代码用于获取存储在作为Salary对象的哈希表位置之一的对象。

myCompay.get(new Integer(i));

之后,它被转换为员工:

(Employee) myCompay.get(new Integer(i));

然后分配给员工参考当前:

Employee current =  (Employee) myCompay.get(new Integer(i));

有人可以向我解释我们是否将存储在哈希表中的对象工资投射到员工对象,然后将其分配给员工参考当前。或者我们是否将参考e1投射到员工参考。有人解释了发生了什么。

4 个答案:

答案 0 :(得分:5)

Java中对象和引用之间的区别有些模糊,因为访问对象的唯一方法是通过引用。进行强制转换时,可以将不同类型的引用引用到同一对象。

请注意,您的代码已损坏:它使用原始哈希代码将对象放入哈希表中,但随后它会尝试使用序列号将其检索回来。除非你很幸运,否则这不会起作用,其中一个对象会返回0..3范围内的哈希码。

答案 1 :(得分:2)

使用转换只会更改引用的类型,它后面的对象将保持不变。

您可以将Contractor投射到Employee(但不需要,因为您已经可以访问Employee中的所有内容), 您还可以将Employee投射到Contractor,然后就可以访问Contractor - 方法和字段(仅当Employee后面的对象是Contractor时,否则你会得到一个例外)。

您无法将Contractor投放到Hourly,因为它们不会相互延伸。 将Contractor投射到Employee然后投放到Hourly会产生异常,因为它背后的对象仍然是Contractor

答案 2 :(得分:1)

你有一些误解: -

  

薪资,小时和承包商都扩展了员工类。

这不是继承的用途。只有Contractor可以被视为Employee的一种类型。 SalaryHourly应为Employee的属性(查找 撰写 )。

此外,正如dasblinkenlight所述,您的检索也会被误解,因为密钥是根据其哈希查找的。查找hashcodeequals合同。

至于你的实际问题。如您所知,get会从此原始Object返回Hashtable。您不能将类型Object的对象实例分配给类型为Employee的引用,因为这样可以允许您在该实例上调用Employee的行为(方法)和{{1 }}类对Object能做什么和不能做什么一无所知。因此,转换为(Employee)实际上是对Employee返回的对象的实际类型的检查,以检查它是否可以合法地分配给get引用。

但是,您不应该使用Java 5中的原始类型。泛型为您提供类型安全性。查找 泛型 以及您不应使用 原始类型 的原因。

答案 3 :(得分:0)

您实际执行的操作是转换哈希表返回的引用,然后将其分配给引用。 请注意,转换不会改变对象(或重新引用) - 它只会告诉程序&#34;处理&#34;铸造的实体作为您铸造的类型。