尝试在Java中初始化Scala创建的类

Aid*_*anc 7 java jvm scala

我正在尝试学习Scala,所以我决定用它来实现数据结构.我已经开始使用Stack了.我创建了以下Stack类.

class Stack[A : Manifest]() {

  var length:Int = -1
  var data = new Array[A](100)

  /**
   * Returns the size of the Stack.
  * @return the size of the stack
  */
 def size = {length} 

  /**
   * Returns the top element of the Stack without
   * removing it.
   * @return Stacks top element (not removed)
   */
  def peek[A] = {data(length)}

  /**
   * Informs the developer if the Stack is empty.
   * @return returns true if it is empty else false.
   */
  def isEmpty = {if(length==0)true else false}

  /**
   * Pushes the specified element onto the Stack.
   * @param The element to be pushed onto the Stack
   */
  def push(i: A){
    if(length+1 == data.size) reSize
    length+=1
    data(length) = i;
  }

  /**
   * Pops the top element off of the Stack.
   * @return the pop'd element.
   */
  def pop[A] = {
    length-=1
    data(length)
  }

  /**
   * Increases the size of the Stack by 100 indexes.
   */
  private def reSize{
    val oldData = data;
    data = new Array[A](length+101)
    for(i<-0 until length)data(i)=oldData(i)
   }
}
Run Code Online (Sandbox Code Playgroud)

然后尝试使用以下内容在我的Java类中初始化此类

Stack<Integer> stack = new Stack<Integer>();
Run Code Online (Sandbox Code Playgroud)

但是,我被告知构造函数不存在,我应该添加一个参数来匹配Manifest.为什么会发生这种情况,我该如何解决?

par*_*tic 18

Alexey给了你正确的解释但是你可以在代码中创建清单(你只需要一个java.lang.Class可以用Java轻松创建的对象).

首先,您应该将一个java友好的工厂方法添加到Stack的伴随对象:

object Stack {
  def ofType[T]( klass: java.lang.Class[T] ) = {
    val manifest =  new Manifest[T] {
      def erasure = klass
    }
    new Stack()(manifest)
  }
}
Run Code Online (Sandbox Code Playgroud)

此方法将生成相应的清单(来自java类),并将其显式传递给Stack构造函数.然后,您可以毫不费力地从Java中使用它:

Stack<String> stack = Stack.ofType( String.class );
stack.push( "Hello" );
stack.push( "World" );

System.out.println( stack.size() );
System.out.println( stack.peek() ); 
Run Code Online (Sandbox Code Playgroud)


Ale*_*nov 9

这是因为绑定的上下文[A : Manifest]只是隐式构造函数参数的简写.所以你的班级"真的"被宣布为class Stack[A]()(implicit m: Manifest[A]) {.因此,创建一个Manifest编译器魔术的唯一方法(据我所知),你不能用Java做到,也不能在Stack那里构建.

您可以更改设计以避免清单,也可以Stack在Scala代码中创建实例,只在Java中使用它们.