カスタムオブジェクトを Java側でつくって JavaScript であれこれしたい場合で、 そのカスタムオブジェクトが配列的なクラスの場合 list[0] のようにアクセスしたときに意図した値を返す方法.
結論としては、ScriptableObject を拡張してつくったサブクラスで Object get(int index, Scriptable start) メソッドをオーバーライドすればOK.
テストのため、このクラスはどの配列の要素にアクセスしても hello という文字列しか返さないようにしてみます. (例によりコードは groovy です.)
class MyArrayList extends ScriptableObject {
    @Override
    String getClassName() { return 'MyArrayList' }
    @Override
    Object get(int index, Scriptable start){
        return 'hello'
    }
}
myArrayList[0] などを JavaScript 側で実行したときに get メソッドが呼ばれます.
このクラスは常に hello 文字列を返すだけの実装になっています.
このJavaScript を実行してみると hello 文字列がかえるはずです.
def script0 = 'new MyArrayList()[999]'
helloMyArrayList.groovy
@Grab(group='org.mozilla', module='rhino', version='1.7.11')
import org.mozilla.javascript.Context
import org.mozilla.javascript.ScriptableObject
import org.mozilla.javascript.Scriptable
class MyArrayList extends ScriptableObject {
    @Override
    String getClassName() { return 'MyArrayList' }
    @Override
    Object get(int index, Scriptable start){
        return 'hello'
    }
}
def script0 = 'new MyArrayList()[999]'
def cx = Context.enter()
def scope = cx.initStandardObjects()
ScriptableObject.defineClass(scope, MyArrayList.class)
def result0 = cx.evaluateString(scope, script0, "<cmd>", 1, null)
println result0
実行してみると
$ groovy helloMyArrayList.groovy
hello
MyArrayList クラスを修正して普通の配列として振る舞うようにします。 具体的には:
修正版 MyArrayList
class MyArrayList extends ScriptableObject {
    private def list = new java.util.ArrayList()
    @Override
    String getClassName() { return 'MyArrayList' }
    @Override
    Object get(int index, Scriptable start){
        if(0<=index && index<list.size()){
            return list.get(index)
        }
        
        return super.get(index, start)
    }
    void jsConstructor() {}
    int jsGet_length(){
        return list.size()
    }
    void jsFunction_push(Object value){
        list.add(value)
    }
}
get メソッドでは、index を範囲チェックした上で、要素数以内ならば、該当要素を返し、そうでなければ、親クラスに処理を任せています.
def script0 = '''\
  var list = new MyArrayList();
  list.push('pika');
  list[0];'''
def cx = Context.enter()
def scope = cx.initStandardObjects()
ScriptableObject.defineClass(scope, MyArrayList.class)
def result0 = cx.evaluateString(scope, script0, "<cmd>", 1, null)
println result0
実行すると意図通り pika が返ります.
これで JavaScript の配列のように振る舞うカスタムオブジェクトをJava側で用意することができました.