ArrayList Implementation in Java
In your ListNode::toString() the use of StringBuilder is useless overhead as you just append one single string. You could strip it down method to just this:

public String toString() {
    if (this.value == null) { // beware of null!
        return "null";
    }
    return this.value.toString();
}

In your List::add(T) method you should throw an Exception (maybe an ArrayIndexOutOfBoundsException with a proper message) if the list is full (if(listSize == initialCapacity) {) instead of writing a note to System.out. Otherwise the calling code of your implementation wouldn't notice the problem. See Fail Fast Principle.
In your add(T) method, why are there two different paths for the first and the other items, when the do exactly the same?
Is it by intention, that you reduce the intial/maximum size of your internal array in the remove(ListNode&lt;T&gt; toBeRemoved, int index) method?

node = new ListNode[--initialCapacity];  // &lt;&lt; newSize = initialCapacity -1


It seems a bit strange to me.


In your remove methods you use initialCapacity where you rather should use listSize (except from the line mentioned in 4a).
Within the remove you could reuse the add method. I would refactor it to something like this:

public boolean remove(T value) {
    boolean result = false;
    for(int i = 0; i &lt; listSize; ++i) { // note: only check elements added
        if(node[i].getValue() == value) {
            result =  remove(node[i], i);
            if(result) {
                listSize--;
            }
            // break; // note: exit loop if you only want to remove first occurence.
        }
    }   
    return result;
}

private boolean remove(ListNode&lt;T&gt; toBeRemoved, int deleteIdx) {
    if(deleteIdx &lt; 0 || deleteIdx &gt;= listSize) { // note: if no element -&gt; exit
        return false;
    }

    if(listSize &gt; 1) { // note: listSize relevant here
        ListNode&lt;T&gt;[] oldNode = node;

        node = new ListNode[initialCapacity]; // note: same size here
        int sourceIdx = 0; 
        for(int targetIdx = 0; targetIdx &lt; listSize; targetIdx++) {
            if (targetIdx == deleteIdx) {
                sourceIdx++; // skip deleted element
            }
            node[targetIdx] = oldNode[sourceIdx++];
        }
    }
    else {
        this.clear();
    }
    return true;
}