Trying to initialize created Scala class in Java

I am trying to learn Scala, so I decided to implement data structures with it. I started from the stack. I created the following Stack class.

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) } } 

I Then try to initialize this class in my Java class using the following

 Stack<Integer> stack = new Stack<Integer>(); 

However, they tell me that the constructor does not exist and that I must add an argument to match the manifest. Why is this happening and how can I fix it?

+7
source share
3 answers

Alexey gave you the correct explanation, but it is certainly possible to create a manifest in your code (you just need a java.lang.Class object that you can easily create in Java).

First you must add the java-friendly factory method to the companion Stack object:

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

This method will generate the appropriate manifest (from the java class) and pass it explicitly to the Stack constructor. Then you can use it with Java without pain:

 Stack<String> stack = Stack.ofType( String.class ); stack.push( "Hello" ); stack.push( "World" ); System.out.println( stack.size() ); System.out.println( stack.peek() ); 
+18
source

This is because the context type [A : Manifest] is simply a shorthand for the implicit constructor argument. Thus, your class is "really" declared as class Stack[A]()(implicit m: Manifest[A]) { . Since the only way to create Manifest is with the magic of the compiler (as far as I know), you cannot do this with Java and you cannot build a Stack there.

You can either change the design to avoid manifestation, or create instances of Stack in Scala code and use them only with Java.

+9
source

Following the paradigmatic answer, you can also create a constructor for your class:

 class Stack[A](implicit m: Manifest[A]) { def this(clazz : Class[A]) { this()(new Manifest[A] { def erasure = clazz }) } 

which can then be called from Java:

 Stack<Integer> s = new Stack<Integer>(Integer.class); s.push(1); System.out.println(s.peek()); 

However, the problem will be in generic types, such as stack stacks of line stacks. To do this, you should study this topic: http://www.scala-lang.org/node/7267

+2
source

All Articles