Correct use of Option in scala? I'm somewhat new to Scala and am not sure if I'm doing things in a very Scala-esque way.

In particular, I'm not sure if I'm using Option correctly, since by calling .isDefined, I'm basically just doing ye olde Java null check. Also, the getMethodAndAnnotationFromInfaces method could probably be done better.

Please point out ways in which I could better leverage language features in the below code:

for (val method &lt;- clazz.getMethods) {
        val methodAndAnnotation = method.getAnnotation(annotationType) match {
            case annotation: MessageHandler =&gt; Some((method, annotation))
            case _ =&gt; getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
        }

        if (methodAndAnnotation.isDefined){
            // do something
        }
    }


getMethodAndAnnotationFromInterfaces function:

def getMethodAndAnnotationFromInterfaces(interfaces: Array[java.lang.Class[_]], method: Method, annotationType: Class[_ &lt;: java.lang.annotation.Annotation])
    : Option[(Method, java.lang.annotation.Annotation)] = {

    @tailrec
    def getMethodAndAnnotationFromInterfacesInner(interfaces: Array[java.lang.Class[_]], acc: Option[(Method, java.lang.annotation.Annotation)])
        : Option[(Method, java.lang.annotation.Annotation)] = {
        interfaces.length match {
            case 0 =&gt; acc
            case _ =&gt;
                try {
                    interfaces.head.getMethod(method.getName, method.getParameterTypes: _*) match {
                        case newMethod: Method =&gt;
                            val newAnnotation = newMethod.getAnnotation(annotationType)
                            if (newAnnotation != null &amp;&amp; acc.isDefined) {
                                throw new RuntimeException("The annotation is applied to the method in more than one interface of the class.")
                            }
                            getMethodAndAnnotationFromInterfacesInner(interfaces.tail, Some((newMethod, newAnnotation)))
                        case _ =&gt; getMethodAndAnnotationFromInterfacesInner(interfaces.tail, acc)
                    }
                } catch {
                    case e: NoSuchMethodException =&gt; getMethodAndAnnotationFromInterfacesInner(interfaces.tail, acc)
                }
        }
    }

    getMethodAndAnnotationFromInterfacesInner(interfaces, None)
}
You could write it like this:

for (val method &lt;- clazz.getMethods) {
  val methodAndAnnotation = method.getAnnotation(annotationType) match {
    case annotation: MessageHandler =&gt; Some((method, annotation))
    case _                          =&gt; getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
  }

  methodAndAnnotation match {
    case Some((method, annotation)) =&gt; // do something
    case None =&gt; //whatever is relevant
  }
}


Or shorter:

for (val method &lt;- clazz.getMethods) {
  method.getAnnotation(annotationType) match {
    case annotation: MessageHandler =&gt;  // do something with method and annotation
    case _                          =&gt; {
      val v = getMethodAndAnnotationFromInterfaces(clazz.getInterfaces, method, annotationType)
      //whatever is relevant
    }
  }
}


But it depends on what you want to do / if you have something to do when getMethodAndAnnotationFromInterfaces returns None.