Scala的Option类有一个orNull方法,其签名如下所示.
orNull [A1 >: A](implicit ev : <:<[Null, A1]) : A1
Run Code Online (Sandbox Code Playgroud)
我被隐含的东西弄糊涂了.有人请说明如何使用它,理想情况下是一个例子吗?
我有一个用Scala编写的应用程序,我的一些团队成员想要它的Java版本.它是一个演示应用程序,使用另一个用Scala编写的API,他们希望Java版本的应用程序能够使用Java中的API.但是,应用程序有点大,我不想手动重新使用Java(他们不想学习Scala).是否有任何工具可以从Scala代码自动生成(可读)Java代码?
我使用Scala的Java Reflection时遇到了问题.我的代码:
case class MyClass(id: String, value: Double)
def create(values: Map[String, Any]): MyClass = {
val constructor = classOf[MyClass].getConstructors.head
val arguments = classOf[MyClass].getDeclaredFields().map( f => values(f.getName) )
constructor.newInstance(arguments: _*).asInstanceOf[MyClass]
}
create(Map("id" -> "CE0D23A", "value" -> 828.32))
Run Code Online (Sandbox Code Playgroud)
我的问题是,我需要传递Map [String,Any],因为其中一个值是Double,但newInstance需要Object,而不是Any.
我尝试使用scalas宇宙:
case class MyClass(id: String, value: Double)
def create(values: Map[String, Any]): MyClass = {
val m = universe.runtimeMirror(getClass.getClassLoader)
val myClass = universe.typeOf[MyClass].typeSymbol.asClass
val cm = m.reflectClass(myClass)
val ctro = universe.typeOf[MyClass].declaration(universe.nme.CONSTRUCTOR).asMethod
val ctorm = cm.reflectConstructor(ctro)
ctorm(values: _*).asInstanceOf[MyClass]
}
create(Map("id" -> "CE0D23A", "value" -> …Run Code Online (Sandbox Code Playgroud) 我目前正在将应用程序的一部分移植到scala,它使用Oval库.方法问题是Validator.validate方法.它有两个 签名:
List<ConstraintViolation> validate(Object validatedObject)
List<ConstraintViolation> validate(Object validatedObject, String... profiles)
Run Code Online (Sandbox Code Playgroud)
scala代码看起来通常如下:
def validate(toValidate: AnyRef) = {
val validator = createValidator
validator.validate(toValidate)
}
Run Code Online (Sandbox Code Playgroud)
并且错误消息:
error: ambiguous reference to overloaded definition,
[INFO] both method validate in class Validator of type (x$1: Any,x$2: <repeated...>[java.lang.String])java.util.List[net.sf.oval.ConstraintViolation]
[INFO] and method validate in class Validator of type (x$1: Any)java.util.List[net.sf.oval.ConstraintViolation]
[INFO] match argument types (AnyRef)
[INFO] this.validator.validate(toValidate)
Run Code Online (Sandbox Code Playgroud)
我怎样才能明白这一点?
在Scala中,我需要覆盖以下给定的Java类和方法:
public abstract class AbstractJava<T> {
protected abstract T test(Class<? extends T> clazz);
}
public class ConcreteJava extends AbstractJava<Object> {
@Override
protected Object test(Class<?> clazz) {
return null;
}
}
// Scala
class ConcreteScala extends ConcreteJava {
protected override def test(clazz: Class[_ <: AnyRef]): AnyRef =
super.test(clazz)
}
Run Code Online (Sandbox Code Playgroud)
我收到了编译错误:
error: ambiguous reference to overloaded definition,
both method test in class ConcreteJava of type
(clazz: java.lang.Class[_])java.lang.Object
and method test in class AbstractJava of type
(clazz: java.lang.Class[_ <: java.lang.Object])java.lang.Object
match argument types …Run Code Online (Sandbox Code Playgroud) 我正在使用一些java.util.Date(它实现java.lang.Comparable)并且希望能够很好地使用它,例如使用<和> =而不是"compareTo(other)== 1".有没有一种很好的方法可以很容易地混合scala.math.Ordered之类的东西没有很多锅炉板?
从Scala版本2.9开始,存在一个方便的转换器,可以java.util.List通过写下这样的内容将其他集合转换为Scala的数据结构:
import scala.collection.JavaConverters._
def scalaVersion = callJavaMethod.asScala
Run Code Online (Sandbox Code Playgroud)
这是一个可爱的小功能,因为它允许在与现有Java代码交互时利用Scala的优势.
但是,我不确定所涉及的时间和空间复杂性,并且在官方文档中找不到任何内容,因此,以下问题:
我在哪里可以获得有关JavaConverters的复杂性(时间和空间)的信息?
我可以在Java中使用scala List,例如:
import scala.collection.immutable.List;
class HelloScalaList {
public static void main (String[] args) {
List xs = List(1, 2, 3);
System.out.println(xs);
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎没有编译.找不到List $ .apply方法.
当我改变它
List xs = Dir.ls()
Run Code Online (Sandbox Code Playgroud)
其中Dir是我的scala类,而ls()返回一个scala List,编译器抱怨
"内部编译器错误:java.lang.ClassCastException:org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding无法强制转换为org.eclipse.jdt.internal中的org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding. compiler.lookup.BinaryTypeBinding.initializeTypeVariable(BinaryTypeBinding.java:927)"
我不知道这是什么意思.
我想在scala中编写一些库,但也希望它在Java中使用.
在我的scala类中有返回scala List的方法,对于java代码使用它们,我有两个选择:
直接在java中使用scala List
编写一个包装器类,为这些方法返回java.util.List.
我更喜欢选项1,因为否则我将不得不为几乎所有我的scala类编写一个包装类.
但我只是无法让scala List在Java中运行.
Scala提供了一个生成Java varargs转发器方法的@varargs注释,可以编写如下内容:
import scala.annotation.varargs
class Foo {
@varargs def foo(args: String*): Unit = {
args.foreach(println)
}
}
Run Code Online (Sandbox Code Playgroud)
然后从Java调用此方法而无需创建scala.Seq:
Foo foo = new Foo();
foo.foo("a", "b");
Run Code Online (Sandbox Code Playgroud)
这很不错.
不幸的是,当方法是抽象的时,似乎没有发生转发部分:
trait Bar {
@varargs def bar(args: String*): Unit
}
class Baz extends Bar {
def bar(args: String*): Unit = {
args.foreach(println)
}
}
Run Code Online (Sandbox Code Playgroud)
现在,如果我们有这个Java代码:
Bar bar = new Baz();
bar.bar("a", "b");
Run Code Online (Sandbox Code Playgroud)
我们得到这个异常(在运行时):
java.lang.AbstractMethodError: Baz.bar([Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)
我们可以用以下方法确认问题javap:
public interface Bar {
public abstract void bar(java.lang.String...);
public abstract void …Run Code Online (Sandbox Code Playgroud) 我有一个生成的java接口,包含一个方法:
public Future<?> getCustomersAsync(AsyncHandler<Customer> asyncHandler);
Run Code Online (Sandbox Code Playgroud)
我想用Akka实现它.我写了以下内容:
override def getCustomerAsync(asyncHandler: AsyncHandler[Customer]): Future[_] = {
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
}
Run Code Online (Sandbox Code Playgroud)
问题是ask退货scala.concurrent.Future[Any]和方法必须返回java.util.concurrent.Future[?].
Error:(33, 17) type mismatch;
found : scala.concurrent.Future[Any]
required: java.util.concurrent.Future[?]
myActorRef.ask(GetCustomer, system.actorOf(Props[Responder]))
^
Run Code Online (Sandbox Code Playgroud)
我该怎么做这个转换?