Search code examples
javacommand-line-argumentsclassnotfoundexception

Class File for T not found


For my assignment, the our programs are tested by running them through the command line, as they take arguments in the forms of file names, so I have to make sure my program runs when run through the command line. When I compile it without issue through jGrasp and eclipse, but when I attempt to compile it through the command line, this is what I get: Cleary.java.35: error: cannot access T Collections.sort(studentObjects, idSorter); class file for T not found

I don't know what T is, and I've never used T as a class in my programs?

Relevant code:

Main Class:

package ClearyAssignment5;

import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
import java.util.*;

public class Cleary {

    public static void main(String[] args) {
        //import the input file and add each line to an ArrayList of the students
          try{
             File input = new File(args[0]);
             Scanner source = new Scanner(input);
             ArrayList<String> listOfStudents=new ArrayList<String>();
             while(source.hasNextLine()){
                listOfStudents.add(source.nextLine());
             }
             ArrayList<Student> studentObjects = new ArrayList<Student>();
             StudentIDComparator idSorter = new StudentIDComparator();
             Collections.sort(studentObjects, idSorter);
             FileWriter writer = new FileWriter(args[1]);
             PrintWriter printWriter = new PrintWriter(writer);
             for(int i=0;i<listOfStudents.size();i++){
                (studentObjects.get(i)).printStudent(printWriter);
             }
             printWriter.close();
        } catch(Exception e) {
            System.out.println("Usage: ClearyAssignment4.Cleary input_file output_file");
        }
    }

}

Student Class:

package ClearyAssignment5;

import java.io.*;
import java.util.ArrayList;
import java.lang.*;
import jva.util.*;

public class Student {
    //Initialize varaibles
    String name;
    int ID;
    float GPA;
    public Student(String studentName, int studentID, float studentGPA){
        //Take the parameters which are passed in, and set them to the variables.
        name = studentName;
        ID = studentID;
        GPA = studentGPA;
    }
       
    public int getID() {
        return ID;
    }

}

Comparator Class:

package ClearyAssignment5;

import java.util.*;
import java.lang.*;
import java.io.*;

class StudentIDComparator implements Comparator<Student> {
    public int compare(Student a, Student b) {
        return a.ID - b.ID;
    }
}

I've removed some of the code which doesn't seem necessary for brevity... any help would be appreciated!


Solution

  • TL;DR: T is a generic type param that javac choked on somehow

    T is a conventional name given to a Generic Type Parameter, which is used for Java's Generics system*. I'm not sure why the compiler choked on it, but the generics system in general has some occasional weird hiccups.


    *An explanation of Generics (in case you haven't heard of them)

    Imagine you are writing a class to hold a list of students. You want to be able to query if a person is on that list, as well as add people to that list. For now, this class will represent a course roster, so that professors can ensure that nobody is sneaking into their classes. Here is what the class will look like:

    public class StudentList {
        public boolean isOnList(Student s) { ... }
        public void addToList(Student s) { ... }
    }
    

    Then imagine you need to create a new version of this class for the staff party at the end of the year, because only some staff are eligible (those who passed their performance review).

    public class StaffList {
        public boolean isOnList(Staff s) { ... }
        public void addToList(Staff s) { ... }
    }
    

    Next, somebody asks you to create a new version of this class to keep track of the TAs for a course, since you can only pass assignments to grade to eligible TAs. You'd create yet another class:

    public class TAList {
        public boolean isOnList(TA t) { ... }
        public void addToList(TA t) { ... }
    }
    

    You eventually get tired of writing such similar classes, so you want to create a single class which can perform all these functions. You would do so using Generics, so that client code can make a PersonList<Student> to hold Students, a PersonList<Staff> to hold Staff, a PersonList<TA> to hold TAs, and any other type of class you want.

    public class PersonList<T> {
        public boolean isOnList(T t) { ... }
        public void addToList(T t) { ... }
    }
    

    The T is a generic type parameter here. When creating an instance of the class PersonList, you pass it a type inside the angle brackets. Then that type replaces all instances of T. The convention is to use single letter names, such as T for type, E for element, K for key, V for value, etc.