0

有一个名为的类Datacenter,其中构造函数是:

public Datacenter(
        String name,
        DatacenterCharacteristics characteristics,
        VmAllocationPolicy vmAllocationPolicy,
        List<Storage> storageList,
        double schedulingInterval) throws Exception {
    super(name);

    setCharacteristics(characteristics);
    setVmAllocationPolicy(vmAllocationPolicy);
    setLastProcessTime(0.0);
    setStorageList(storageList);
    setVmList(new ArrayList<Vm>());
    setSchedulingInterval(schedulingInterval);

    for (Host host : getCharacteristics().getHostList()) {
        host.setDatacenter(this);
    }

    // If this resource doesn't have any PEs then no useful at all
    if (getCharacteristics().getNumberOfPes() == 0) {
                throw new Exception(super.getName()
                    + " : Error - this entity has no PEs. Therefore, can't process any Cloudlets.");
    }

    // stores id of this class
    getCharacteristics().setId(super.getId());
}

我们使用这个类在程序中制作数据中心:

private static Datacenter createDatacenter(String name, LinkedList myHarddriveList, double timeZone) {

    /* Additional codes like defining Hots */

    Datacenter datacenter = null;
    try {
        datacenter = new Datacenter(name, characteristics, 
                            new VmAllocationPolicySimple(hostList), myHarddriveList, 0);
    } catch (Exception e) {
                System.out.println("Error: " + e);
    }

    return datacenter;
}

运行程序的结果是这样的:

在此处输入图像描述

问题是,如果我通过扩展类来定义自己的数据中心,Datacenter程序将无法工作。我将MyDatacenter类定义如下:

public class MyDatacenter extends Datacenter{

    /* My own variables */

    public MyDatacenter(String name, 
           DatacenterCharacteristics characteristics, 
           VmAllocationPolicy vmAllocationPolicy,
           List<Storage> storageList, 
           double schedulingInterval) throws Exception {
        super(name, 
                characteristics, 
                vmAllocationPolicy,
                storageList, 
                schedulingInterval);
    }

    /* My own mwthods */

}

因此,如果我将方法的返回类型createDatacenter()Datacenter更改MyDatacenter为程序将不起作用。

private static MyDatacenter createDatacenter(String name, LinkedList myHarddriveList, double timeZone) {

    /* No changes */

    MyDatacenter datacenter = null;
    try {
        datacenter = new MyDatacenter(name, characteristics, 
                            new VmAllocationPolicySimple(hostList), myHarddriveList, 0);
    } catch (Exception e) {
                System.out.println("Error: " + e);
    }

    return datacenter;
}

不会将 cloudlet 分配给任何数据中心:

在此处输入图像描述

我什至无法将创建的Datacenter实例转换为MyDatacenter.

4

2 回答 2

1

As per the comments on your question the problem seemed to be you overriding methods like setCharacteristics(...), setSchedulingInterval(...) etc. and calling those methods in the super constructor.

Without knowing much more about what your system is doing and how overriding those methods affects the inner workings of your application it's hard to give an exact example of the problems you could face. Thus I'll try to provide a more abstract example and hope that I can convey the idea of what could go wrong.

Let's say we have the following classes:

class SuperType {
  protected String name;

  public SuperType(String n) {
    setName( n );
  }

  protected void setName( String n ) {
    name = n;
  }    
}

class SubType extends SuperType {
  // setting 'id' happens here
  private int id = new Random().nextInt() + 1;

  {
    // initializer block, setting 'id' could happen here       
  }

  public SubType( String n ) {
    super( n ); 
    // setting 'id' could happen here as well
  }

  @Override
  protected void setName( String n ) {
    name = n + " " + id;
  }    
}

As you can see SubType overrides the method setName(...) that's used in the SuperType constructor. Why is that a problem?

Consider the order in which initialization happens when we call new SubType("some name"):

  • The constructor SubType(...) calls the super constructor, i.e. SuperType(...)
  • Before the constructor is executed the instance will be created and initialized.
    This happens in the following order for each class in the hierarchy from top to bottom (super to sub types)
    • fields in the order they're listed
    • initializer blocks in the order they're listed
    • constructor

Thus we have the following execution order in our example (I'll leave Object and non-existant initializations for simplicity)

  • SuperType(...) constructor (because there's no initializer block)
  • setName(...) is being called but that's the overridden version
  • SubType fields are initialized, setting id to a random number
  • SubType intializer blocks run
  • SubType(...) constructor runs

As you can see, the overridden setName(...) is executed before id is initialized so all that method will see will be its default value (0 for primitive int). And depending on your application that could be the problem - the overridden method might rely on some of the additional variables being initialized properly (e.g. not null) and if that doesn't happen the instances might still be created but not be usable from your application's point of view.

于 2019-10-21T08:51:11.933 回答
0

当你有类似的东西时:

Datacenter d = new MyDatacanter(...);

唯一可访问的方法d是在超类中定义的方法Datacenter,除非您将其转换dMyDatacenter对象:

d.yourCustomMethod(); //won't work
((MyDataCenter) d).yourCustomMethod(); //should work fine
于 2019-10-18T13:59:00.723 回答