不兼容的对象类型 - Java

Incompatible Object Types - Java

我正在尝试实现一个小的 Java 程序,该程序显示进程调度的工作原理。我当前的代码如下。我遇到的问题是来自 ProcessScheduler class 的静态方法 CPU.executeInstructions(Process process)firstComeFirstServed()。我的程序目前无法编译,因为它给出

incompatible type error: Object can not be converted to Process

来自 firstComeFirstServed().

我设法通过将 executeInstructions() 参数从 Process process 更改为 Object process 使其编译,但据我所知,之前的方法签名没有任何问题.我在程序周围调用了几个 System.out.println() 来将 class 打印到屏幕上,这确认正在操作的对象是一个 Process 对象。有人可以解释这里发生了什么吗?我 missing/not 了解什么?

package processes;

import java.util.logging.Level;
import java.util.logging.Logger;
import processes.ProcessScheduler.Algorithm;

public class ProcessManager {
    private static Thread psThread;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // Create process table
        ProcessTable pt;
        //System.out.println("1 " + pt.getClass());
        // Creat Process Scheduling Thread.
        psThread = new Thread(new ProcessScheduler(Algorithm.FIRST_COME_FIRST_SERVE, pt = new ProcessTable()));
        System.out.println("2 " + pt.getClass());
        // Start Thread
        psThread.start();
        System.out.println("3 " + pt.getClass());
        try {
            // Add Process' to table
            String[] instrucSet = {"sout","name"};
            for(int i = 0; i < 5; i++){
                pt.add(new Process(ProcessTable.processCounter, i + 1, 10 - i, instrucSet));
            }
            Thread.sleep(4000);
            for(int i = 0; i < 5; i++){
                pt.add(new Process(ProcessTable.processCounter, i + 1, 10 - i, instrucSet));
            }
            Thread.sleep(2000);
            ProcessScheduler.run = false;

        } catch (InterruptedException ex) {
            Logger.getLogger(ProcessManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}



package processes;

public class Process {
    private int quanta, priority, pID;
    private String [] instructions;


    /**
     * Constructor for Process class.
     * @param p_id process id
     * @param instruction_set Instructions to be processed by the CPU.
     * @param quanta Represents length of time (known or estimated) taken to execute process
     */
    public Process(int p_id, int quanta, String instruction_set[]){
        // Initialise instance variables
        this.pID = p_id;
        this.quanta = quanta;
        this.instructions = instruction_set;
    }

    /**
     * Constructor for Process class.
     * @param quanta Represents length of time (known or estimated) taken to execute process
     * @param priority Represents the priority of the process, from 1 to infinity with 1 having highest priority.
     * @param instruction_set Instructions to be processed by the CPU.
     */
    public Process(int p_id,int quanta, int priority, String instruction_set[]){
        // Initialise instance variables
        this.pID = p_id;
        this.quanta = quanta;
        this.priority = priority;
        this.instructions = instruction_set;
    }

    /**
     * @return Returns length of process, which may either be a known or estimated quantity.
     */
    public int getQuanta() {
        return quanta;
    }

    /**
     * @return Returns process priority level.
     */
    public int getPriority() {
        return priority;
    }

    /**
     * @return Returns process id, a unique value generated when the process is accepted onto the process table.
     */
    public int getpID() {
        return pID;
    }

    /**
     * @return Returns an array holding the instructions to be processed for this process.
     */
    public String[] getInstructions() {
        return instructions;
    }

    @Override
    public String toString(){
        return "Process ID: " + this.getpID() + ". Quanta: " + this.getQuanta() + ". Priority: " + this.getPriority();
    }

}


package processes;

import java.util.ArrayList;

/**
 *
 * @author dave
 */
public class ProcessTable extends ArrayList {

    // P_id counter;
    public static int processCounter = 0;

    public ProcessTable(){
        super();
    }

    /**
     * Adds the specified process to the collection and increments the processCounter
     * @param aProcess The process to be added to the Process Table.
     * @return Returns true if successfully added.
     */
    public boolean add(Process aProcess){
        boolean sucessful = super.add(aProcess);
        if(sucessful)
            processCounter++;
        return sucessful;
    }

    /**
     * Prints the process table to console.
     */
    public void displayProcessTable(){

        for(int i = 0; i < this.size(); i++){
            System.out.println(this.get(i).toString());
        }
    }
}


package processes;

/**
 *
 * @author dave
 */
public final class CPU {

    private CPU(){

    }

    public static void executeInstructions(Process process){
        System.out.println(process.toString());        
    }

}


package processes;

import java.util.logging.Level;
import java.util.logging.Logger;


/**
 *
 * @author dave
 */
public class ProcessScheduler implements Runnable {    
    public static boolean run;
    // The algorithm to be used.
    private String alg;
    // To hold reference to a Proces Table.
    public static ProcessTable pt;

    // Class constants for scheduling algorithm type. Used in class constructor.
    // Enum for 
    public enum Algorithm {FIRST_COME_FIRST_SERVE, SHORTEST_JOB_FIRST, ROUND_ROBIN, PRIORITY_QUEUE};  

    /**
     * @param scheduling_algorithm Sets the scheduling algorithm to be used when
     * @param process_table A Process Table instant that Process will be added to.
     * passing jobs to the CPU for execution.
     */
    public ProcessScheduler(Algorithm scheduling_algorithm, ProcessTable process_table){
        //System.out.println("4 " + pt.getClass());
        // Create reference Process Table
        //pt = new ProcessTable();
        pt = process_table;
        System.out.println("5 " + pt.getClass());
        // Start scheduling based on algorithm represented by enum in constructor arg.
        switch(scheduling_algorithm){
            case FIRST_COME_FIRST_SERVE:
                alg = "fcfs";
                break;
            case SHORTEST_JOB_FIRST:
                alg = "sjf";
                break;
            case ROUND_ROBIN:
                alg = "rr";
            case PRIORITY_QUEUE:
                alg = "pq";
            default:
                alg = "pq";
                break;
        }
    }

    /**
     * Start Scheduling processes to the CPU
     */
    public void run() {        
        //boolean run = true;
        int sleepTime = 1000;
        //Display algorithm to screen
        try {
            run = true;
            while(run){
                if(!pt.isEmpty()){
                    switch (alg) {
                        case "fcfs":
                            System.out.println("6 " + pt.getClass());
                            firstComeFirstServed();
                            break;
                        case "sjf":
                            shortestJobFirst();
                            break;
                        case "rr":
                            roundRobin();
                            break;
                        case "pq":
                            priorityQueue();
                            break;
                    }
                } else {
                    Thread.sleep(sleepTime);
                }
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(ProcessScheduler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * Executes all processes in Process Table on a First Come First Served 
     * basis (the order in which they were added to the collection).
     */
    private void firstComeFirstServed(){
        System.out.println("7 " + pt.getClass());
        for(int i = 0; i < pt.size(); i++){
            CPU.executeInstructions(pt.get(i));
        }

        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(ProcessScheduler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private void shortestJobFirst(){
        System.out.println("in SJF");
    }
    private void roundRobin(){
        System.out.println("in RR");
    }
    private void priorityQueue(){
        System.out.println("in PQ");
    }

}

问题是扩展 ArrayList 的 ProcessTable class 不是通用的。 您可以先用

修改它
public class ProcessTable<E> extends ArrayList<E> {

然后当你实例化它时,你可以指定 class 类型 ProcessTable 将包含在

ProcessTable<Process> pt;

这样编译器就会知道 class 将 return 调用 pt.get(i)

如果没有,它将把它当作对象。

编辑: 正如@EJP 指出的那样,更具体地针对您的问题,您可能希望使用特定的 class 类型扩展 ArrayList 它将与

一起使用
public class ProcessTable extends ArrayList<Process>

您的 ProcessTable 定义应该是这样的:

public static class ProcessTable extends ArrayList<Process>

正如其他人指出的那样,ProcessTable 应该扩展 ArrayList<Process>。但是 ProcessTable class 根本没有太多理由存在。所做的只是提供一个错误实现的计数器(不应该是静态的)和一个显示方法。我会删除它并只使用 ArrayList<Process>.