scala编译出来的class可以用反射区调用。比如scala代码如下
private def updateWeightsAndGaussians(
mean: BDV[Double],
sigma: BreezeMatrix[Double],
weight: Double,
sumWeights: Double): (Double, MultivariateGaussian) = {
val mu = (mean /= weight)
BLAS.syr(-weight, Vectors.fromBreeze(mu),
Matrices.fromBreeze(sigma).asInstanceOf[DenseMatrix])
val newWeight = weight / sumWeights
val newGaussian = new MultivariateGaussian(mu, sigma / weight)
(newWeight, newGaussian)
}
我们可以用下面的代码调用
Method method = GaussianMixture.class.getDeclaredMethod( "org$apache$spark$mllib$clustering$GaussianMixture$$updateWeightsAndGaussians", DenseVector.class, DenseMatrix.class,double.class,double.class );
method.setAccessible( true );
GaussianMixture gau = new GaussianMixture();
gau.setK( 2 ).setConvergenceTol( 0.01 ).setMaxIterations( 2 ).setSeed( 10 );
Vector v = Vectors.dense( new double[]{1,2,3} );
Matrix m = Matrices.dense( 3, 3, new double[]{1,1,1,1,1,1,1,1,1} );
Object obj = method.invoke( gau, v.toBreeze( ), m.toBreeze( ), 1.0, 3.0 );
System.out.println( obj );
要点是,反射的名字最好用用Method[] ms = GaussianMixture.class.getDeclaredMethods( )来确定名字,用 m.getParameterTypes( ) 来查看参数,然后在确定参数。
Double类型要用 double.class.
Method method = null;
Method[] ms = GaussianMixture.class.getDeclaredMethods( );
for (Method m:ms)
{
System.out.println( m.getName( ) );
if (m.getName( ).indexOf( "updateWeightsAndGaussians" ) > -1)
{
method = m;
Class[] cs = m.getParameterTypes( );
for (Class c:cs)
{
System.out.println( c.getName( ) );
}
}
}