简介:DSCI提供建立和处理组件对象在DATA STEP程序中,JAVAOBJ就是这样的一个对象,其提供类似JNI的机制,可实例化JAVA类,访问对象属性和方法
定义JAVA对象
其由DECLARE语法支持:
declare javaobj j("类名");
这样将定义和存储一个对象的实例在标量J中, JAVAOBJ会将JAVA CLASSPATH下的someJavaClass实例化呈现出来 典型的,为确保实例化J只一次,可以这样做
if _N_ = 1 then do; declare javaobj j("someJavaClass"); end;
JAVAOBJ也能使用_new_ 语法进行实例化
declare javaobj j; j = _NEW_ javaobj("someJavaClass");
构造参数
JAVAOBJ构造一个对象的实例的第一个参数是JAVA类的名字,如建立一个hashtable对象
declare javaobj h("java/util/Hashtable");
其他相应的参数也可以依次传给java class本身
如建立一个容量为100、系数为0.8的hashtable对象,我们应该封装java/util/Hashtable类且在DATA STEP中实例化它
import java.util.*; public class mhash extends Hashtable { mhash(double size, double load) { super((int)size, (float)load); } }
declare javaobj h("mhash", 100, .8); 封装类是必须的,因为DATA STEP中的数字类型对应JAVA中的double
访问对象属性 一旦对象被实例化,JAVAOBJ是容许用户用方法访问和修改对象属性,如设想我们由这样一个类
import java.util.*; import java.lang.*; public class ttest { public int i; public double d; public String s; }
我们建立这个类的实例,用set/get访问对象属性在下列程序中
data _null_; dcl javaobj j("ttest"); length val 8; length str $20; j.setIntField("i", 100); j.setDoubleField("d", 3.14159); j.setStringField("s", "abc"); j.getIntField("i", val); put val=; j.getDoubleField("d", val); put val=; j.getStringField("s", str); put str=; run;
set/get方法的第一个参数是属性名,第二个参数是get/set的变量或值
访问对象方法 可以把上面的类改造成这样
import java.util.*; import java.lang.*; public class ttest { public int i; public double d; public String s; public int im() { return i; }
public String sm() { return s; }
public double dm() { return d; } }
我们可以通过javaobj方法调用访问java 值,如
data _null_; dcl javaobj j("ttest"); length val 8; length str $20; j.setIntField("i", 100); j.setDoubleField("d", 3.14159); j.setStringField("s", "abc");
j.callIntMethod("im", val); put val=; j.callDoubleMethod("dm", val); put val=; j.callStringMethod("sm", str); put str=; run;
注:方法的返回值总是被指定为最后一个参数,例如,我们有个返回为double的方法
public double m(double x, double y) { return x * y; }
那么在DATA STEP中调用该方法用下列语法
length val1 val2 ret 8; j.callDoubleMethod("m", val1, val2, ret);
访问类的属性和方法 访问类的静态属性和方法,我们可以使用相应的JAVAOBJ方法,例如
import java.util.*; import java.lang.*; public class ttestc { public static double d; public static double dm() { return d; } }
在DATA STEP中调用
data x; dcl javaobj j("ttestc"); length d 8; j.callSetStaticDoubleField("d", 3.14159); j.callStaticDoubleMethod("dm", d); put d=; run;
数据类型使用
java数据类型集是data step的超集,后者的主要类型是数字型和字符型,而JAVA除了包含数字型和字符型还含有如byte,char,short等类型。
当使用javaobj方法调用是所有java数字类型对应DATA STEP中的数组类型,JAVA STRING则映射到DATA STEP的字符类型(为UTF串),字符型不能被映射到data step中,且不能由java clasS返回对象到data step中(string对象除外),但是容许传送对象到java class中
某些JAVA类返回对象,我们可以封装改类以获得对象的值,例如
import java.util.*; public class mhash { private Hashtable table;
public mhash() { table = new Hashtable(); }
public void put(double key, double value) { table.put(new Double(key), new Double(value)); }
public void put(String key, String value) { table.put(key, value); }
public double get(double key) { Object ret = table.get(new Double(key)); if (ret instanceof Double) return ((Double)ret).doubleValue(); else return Double.NaN; }
public String get(String key) { return (String)table.get(key); } }
data step中使用
data _null_; length s $20; /* * Simple Java hash table test. mhash.class is a wrapper * for java/util/Hashtable - so that we can pass Java strings * directly instead of generic Objects. */ declare javaobj h("mhash");
/* Load up the table */ h.callVoidMethod("put", "key1", "data1"); h.callVoidMethod("put", "key2", "data2"); h.callVoidMethod("put", "key3", "data3"); h.callVoidMethod("put", "key4", "data4"); h.callVoidMethod("put", "key5", "data5"); /* Retrieve a value */ h.callStringMethod("get", "key3", s); put s=; run;
数组使用
data step数组能直接传到java对象中,如 import java.util.*; import java.lang.*; class jtest { public void dbl(double args[]) { for(int i = 0; i < args.length; i++) System.out.println(args[i]); } public void str(String args[]) { for(int i = 0; i < args.length; i++) System.out.println(args[i]); } }
data _null_; dcl javaobj j("jtest"); array s[3] $20 ("abc", "def", "ghi"); array d[10] (1:10); j.callVoidMethod("dbl", d); j.callVoidMethod("str", s); run;
|