scala> def classMath( x: AnyRef ): Unit = { | x match { | case A(a) => println( "A:" + a ) | case B(b) => println( "B:" + b ) | case A => println( A.apply(100) ) | } | } classMath: (x: AnyRef)Unit
scala> val a = A( 1 ) a: A = A(1)
scala> val b = B( "b" ) b: B = B(b)
scala> classMath( a ) A:1
scala> classMath( b ) B:b
也许你已经知道,在模式匹配中,当你的 case class 没有参数的时候,你是在使用 case object 而不是一个空参数列表的 case class
1 2
scala> classMath( A ) A(100)
除了在模式匹配中使用之外,unapply 方法可以让你结构 case class 来提取它的字段,如:
1 2
scala> val Person(lastname, _, _) = p lastname: String = Lacava
你可能不知道的知识
获取一个函数接收一个 tuple 作为参数,该 tuple 的元素类型与个数与某 case class 相同,那么可以将该 tuple 作为 case class 的 tuple 方法参数来构造 case class 实例
scala> Person.tupled( meAsTuple ) res2: Person = Person(Lacava,Alessandro,1976)
相对用 tuple 来创建 case class 实例,还可以从 case class 实例中解构并提取出 tuple 对象
1 2 3 4 5 6 7
scala> val transform: Person => Option[ (String, String, Int) ] = { | Person.unapply _ | } transform: Person => Option[(String, String, Int)] = <function1>
scala> transform( p ) res0: Option[(String, String, Int)] = Some((Lacava,Alessandro,1976))
另一种定义 case class 的方式
还有另一种很少人知道的定义 case class 的方式,如:
1
case class Person( lastname: String )( firstname: String, birthYear: Int )
这种方式有点像偏函数,有两个参数列表,要注意的是,对这两个参数列表是区别对待的。上文提到的所有 case class 的特性在这种定义方式下只作用于第一个参数列表中的参数(比如在参数前自动加 val,模式匹配,copy 支持等等),第二个及之后的参数列表中的参数和普通的 class 参数列表参数无异。
firstname和birthYear前不再自动添加 val,不再是类的成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
scala> val p = Person("Lacava")("Alessandro", 1976) p: Person = Person(Lacava)
scala> p.lastname res0: String = Lacava
scala> p.firstname <console>:11: error: value firstname is not a member of Person p.firstname ^
scala> p.birthYear <console>:11: error: value birthYear is not a member of Person p.birthYear ^
copy 时,当不指定birthYear的值时,不会使用 p 中的birthYear,因为根本没这个值,会报错
1 2 3 4
scala> p.copy()(firstname = "Jhon") <console>:11: error: not enough arguments for method copy: (firstname: String, birthYear: Int)Person. Unspecified value parameter birthYear. p.copy()(firstname = "Jhon")
equals 和 toString 方法也发生了改变:
1 2 3 4 5 6 7 8 9 10 11
scala> val p_1 = Person("Lacava")("Jhon", 2001) p_1: Person = Person(Lacava)
class Student(var ID : String, var Name : String) { println("主构造器!") }
主构造器直接跟在类名后面,主构造器的参数最后会被编译成字段
主构造器执行时,会执行类中所有的语句
如果主构造器参数声明时不加val或var,相当于声明为private级别
(2)从构造器
1 2 3 4 5 6 7 8 9 10 11 12 13 14
class Student(var ID : String, var Name : String) { println("主构造器!") var Age : Int = _ var Address : String = _ private val Email : String = Name + ID + "@163.com" println("从构造器!") def this(ID:String, Name:String, Age:Int, Address:String){ this(ID, Name) this.Age = Age this.Address = Address } }
connect to zl user test using testtest; loadclientfrom'E:\zds\czj_data\test-20091029'of del insertinto test_tmp; update CCARD.card set SPLIT_DATE = '20161111'where SPLIT_DATE isnull connectreset;
Exception in thread "main" java.io.InvalidClassException: serilize.Student; local class incompatible: stream classdesc serialVersionUID = 6643383736516292602, local classserialVersionUID= -1315177638240754633
使用监听器(TriggerListener, JobListener or SchedulerListener)
通过在 JobListener.jobWasExecuted() 中 立即执行一个新的任务。
这种方法可能侵入性比较强,因为需要在监听器中定义任务的关联关系和需要考虑任务信息的持久化。
One way is to use a listener (i.e. a TriggerListener, JobListener or SchedulerListener) that can notice the completion of a job/trigger and then immediately schedule a new trigger to fire. This approach can get a bit involved, since you’ll have to inform the listener which job follows which and you may need to worry about persistence of this information.
二、使用 JobDataMap
在 JobData 中保存下一个执行任务的标识,在执行的最后执行下一个任务。
Another way is to build a Job that contains within its JobDataMap the name of the next job to fire, and as the job completes (the last step in its Execute() method) have the job schedule the next job.