??xml version="1.0" encoding="utf-8" standalone="yes"?> 一、去q曾l做q一个JAVA和C通信的项目,用C语言实现某个特定功能函数Q然后在JAVA中调用。最q又有朋友问P于是做q的东西整理成学习笔讎ͼ希望对后来者有所帮助Q呵c?/p> 二、jni例子?/p> jni-java native interface是java与其他语a本地通信的接口,按照jni的约定,javaE序可以调用其他语言~写的函敎ͼ其他语言也可以调用java实现的方法,本文介绍了一个最单的java调用cҎ的例子。主要由两部分组成, 一个是javaȝ序,另一个是被调用的dllQ由C语言实现Q?/p> 三、编写步?/p> 1、javaȝ?/p> //文gtestdll.java public class testdll /*下面两个函数为C语言实现的方?/ //d?br /> public static void main(String[] args) 2、得到C所需的头文g 执行如下命oQ假设jdk的安装\径ؓD:\Java\jdk1.5.0\binQ?/p> D:\Java\jdk1.5.0\bin\javac testdll.java #生成testdll.class文g D:\Java\jdk1.5.0\bin\javah testdll #Ҏtestdll.class生成testdll.h文g 3、用c语言生成所需的dll (1) 打开vc6, 建立一个空的dll目?/p> 菜单里?File"->New->Projects->Win32 dynamic link library,目名ؓgookluckQ与java文g中的调用库名保持一_Q第二步里选an empty DLL project. (2)把前面生成的testdll.h复制到这个项目中Q再新添下面的testdll.cpp文g #include "testdll.h" int i = 0; JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j) 此时~译会报错,因ؓq缺几个头文gQ因此要把下面两个文件复制到目目录中或者vc的头文g目录 (即Microsoft Visual Studio\VC98\Include)?jni.h文g和jni_md.h文gQ在我机器这两个文g原始目录?/p> D:\Java\jdk1.5.0\include\jni.h D:\Java\jdk1.5.0\include\win32\jni_md.h 再次~译Q运行通过 4、测试运?/p> ?中得到的testdll.dll文g拯到testdll.class所在目录下Q执?/p> D:\Java\jdk1.5.0\bin\java testdll q行l果?/p> 10 说明调用正确?br /> 五、几个注意事?/p> 1、System.loadLibrary("goodluck"); 一句,有时在别的情况下会报错,主要原因是程序找不到q个库文件所在的路径Q此时可以检查path环境变量是否包含了合适的路径Q或者把dll文g拯到系l的dll目录下,如C:\WINNT\system32?/p> 2、库文g不必写后~名,写了反而可能错Q因时程序会Ltestdll.dll.dll文gQ自然是不存在了Q? 3、要调用的方法做本地声明Q关键字为native。ƈ且只需要声明,而不需要具体实现。如Q? 4、函数返回类型尽量用jni中的基本cdQ如整型、字W等Q,最好不要返回自定义的类Q那样在c里有可能会引起错误?/p> 5、在c中写具体实现的时候,我们只关心两个函数原? JNICALL告诉C~译器参数进栈的方式Q我们不必关? jint是以JNIZ介JAVA的intcd与本地c语言的int沟通的一U类型,我们当做int使用。其他类型名可以Ljni帮助文. 函数的名U是JAVA_再加上javaE序的package路径再加函数名组成的?/p> 参数中,我们也只需要关心在JAVAE序中存在的参数Q即W三个往后的参数。至于JNIEnv*和jclass我们一般没有必要去它?/p> 知道q些U定后,我们没有javahE序也可以自己手工写出testdll.h文g来,不过ȝ些就是了^O^ 六、jni的其他参考资?/p> jni属于java语言的一部分Q其权威资料自然要到sun的站点上查找(www.sun.com) 以下是我在sun公司|站上找到的一些页?/p> http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html l出了一个jni的例子, http://java.sun.com/j2se/1.4.2/docs/guide/jni/index.html l出了完整的jni介绍Q?/p> 另外Qlinux下jni的例子可以参?a >http://www.linuxmine.com/5629.html 七、附javah生成的testdll.h文g?/p> /* DO NOT EDIT THIS FILE - it is machine generated */ #ifndef _Included_testdll /* /* #ifdef __cplusplus
{
static
{
System.loadLibrary("goodluck"); //goodluck用的库名,不必加dll后缀
}
public native static int get();
public native static void set(int i);
{
testdll test = new testdll();
test.set(10); //调用了在C中实现的Ҏset
System.out.println(test.get()); //调用了在C中实现的Ҏget
System.out.println("hello world!\n");
}
}
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
{
return i;
}
{
i = j;
}
hello world!
public native static void set(int i);
public native static int get();
JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
q里JNIEXPORT都是JNI的关键字Q表C此函数是要被java调用的,如果是其他语a调java语言QJNIEXPORTp变成JNIIMPORT了?/p>
#include "jni.h"
/* Header for class testdll */
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get
(JNIEnv *, jclass);
* Class: testdll
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_testdll_set
(JNIEnv *, jclass, jint);
}
#endif
#endif
]]>
Integer k1 = 128;
Integer k2 = 128;
System.out.println( k1==k2); //False
Integer w1 = -128;
Integer w2 = -128;
System.out.println( w1==w2); //True
Integer m1 = -129;
Integer m2 = -129;
System.out.println( m1==m2); //False
I've seen a lot of posts in this thread about what is happening on ==
It's simple:
When we do
Integer i = 127;
autoboxing turns this into:
Integer i = Integer.valueOf( 127 );
Go look at the implementation of Integer.valueOf(), and you'll find:
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
If the int value is between -128 and 127, it will return a cached Integer value. This way we avoid creating many duplicate Integer objects for those common values. It save's on memory and improves performance.
And, of course, it does mean that Integer i = 127 will always return the same Integer instance.
再联惛_以前讨论的String问题Q?br /> String a = new String("Hello World");
String b = "Hello World";
String c ="Hello World";
q里创徏了几个对象,a==b么?b==c么?
q里只创Z两个新对象,一个是“Hello World”对象,另一个是与“Hello World”有相同值的对象。a b c都是对象引用。其中a==b为fasleQ因为a b指向不同的对象,b==c为trueQ这是因为b c都指向同一个对象。因为String是一个不可变的对象,而String的直接量赋g自动L以前生成了的内容相同的实例赋l引用,若以前没有内容相同的实例存在Q则创徏新实例。故会发生b==c?/font>
1 protected void collectionsExample() {
2 ArrayList list = new ArrayList();
3 list.add(new String("test string"));
4 list.add(new Integer(9)); // purposely placed here to create a runtime ClassCastException
5 inspectCollection(list);
6 }
7
8
9 protected void inspectCollection(Collection aCollection) {
10 Iterator i = aCollection.iterator();
11 while (i.hasNext()) {
12 String element = (String) i.next();
13 }
14 }
1 protected void collectionsExample() {
2 ArrayList<String> list = new ArrayList<String>();
3 list.add(new String("test string"));
4 // list.add(new Integer(9)); this no longer compiles
5 inspectCollection(list);
6 }
7
8
9 protected void inspectCollection(Collection<String> aCollection) {
10 Iterator<String> i = aCollection.iterator();
11 while(i.hasNext()) {
12 String element = i.next();
13 }
14 }
1 public class ArrayList<E> extends AbstractList<E> {
2 // details omitted...
3 public void add(E element) {
4 // details omitted
5 }
6 public Iterator<E> iterator() {
7 // details omitted
8 }
9 }
1 public <T extends Comparable> T max(T t1, T t2) {
2 if (t1.compareTo(t2) > 0)
3 return t1;
4 else return t2;
5 }
1 Integer iresult = max(new Integer(100), new Integer(200));
2 String sresult = max("AA", "BB");
3 Number nresult = max(new Integer(100), "AAA"); // does not compile
List<String> stringList = new ArrayList<String>(); //1
List<Object> objectList = stringList ;//2
objectList .add(new Object()); // 3
String s = stringList .get(0);//4
void printCollection(Collection<Object> c)
{ for (Object e : c) {
System.out.println(e);
}}
void printCollection(Collection<?> c)
{ for (Object e : c) {
System.out.println(e);
}}
class NonGen {
Object ob; // ob is now of type Object
// Pass the constructor a reference to
// an object of type Object
NonGen(Object o) {
ob = o;
}
// Return type Object.
Object getob() {
return ob;
}
// Show type of ob.
void showType() {
System.out.println("Type of ob is " +
ob.getClass().getName());
}
}
// Demonstrate the non-generic class.
public class NonGenDemo {
public static void main(String args[]) {
NonGen iOb;
// Create NonGen Object and store
// an Integer in it. Autoboxing still occurs.
iOb = new NonGen(88);
// Show the type of data used by iOb.
iOb.showType();
// Get the value of iOb.
// This time, a cast is necessary.
int v = (Integer) iOb.getob();
System.out.println("value: " + v);
System.out.println();
// Create another NonGen object and
// store a String in it.
NonGen strOb = new NonGen("Non-Generics Test");
// Show the type of data used by strOb.
strOb.showType();
// Get the value of strOb.
// Again, notice that a cast is necessary.
String str = (String) strOb.getob();
System.out.println("value: " + str);
// This compiles, but is conceptually wrong!
iOb = strOb;
v = (Integer) iOb.getob(); // runtime error!
}
}
class Example1<T>{
private T t;
Example1(T o){
this.t=o;
}
T getOb(){
return t;
}
void ShowObject(){
System.out.println("对象的类型是Q?+t.getClass().getName());
}
}
public class GenericsExample1 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Example1<Integer> examplei=new Example1<Integer>(100);
examplei.ShowObject();
System.out.println("对象是:"+examplei.getOb());
Example1<String> examples=new Example1<String>("Bill");
examples.ShowObject();
System.out.println("对象是:"+examples.getOb());
}
}
class TwoGen<T, V> {
T ob1;
V ob2;
// Pass the constructor a reference to
// an object of type T.
TwoGen(T o1, V o2) {
ob1 = o1;
ob2 = o2;
}
// Show types of T and V.
void showTypes() {
System.out.println("Type of T is " +
ob1.getClass().getName());
System.out.println("Type of V is " +
ob2.getClass().getName());
}
T getob1() {
return ob1;
}
V getob2() {
return ob2;
}
}
public class GenericsExampleByTwoParam {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TwoGen<Integer, String> tgObj =
new TwoGen<Integer, String>(88, "Generics");
// Show the types.
tgObj.showTypes();
// Obtain and show values.
int v = tgObj.getob1();
System.out.println("value: " + v);
String str = tgObj.getob2();
System.out.println("value: " + str);
}
}
class Stats<T extends Number> {
T[] nums; // array of Number or subclass
// Pass the constructor a reference to
// an array of type Number or subclass.
Stats(T[] o) {
nums = o;
}
// Return type double in all cases.
double average() {
double sum = 0.0;
for(int i=0; i < nums.length; i++)
sum += nums[i].doubleValue();
return sum / nums.length;
}
}
public class GenericsExampleByHierarchy {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer inums[] = { 1, 2, 3, 4, 5 };
Stats<Integer> iob = new Stats<Integer>(inums);
double v = iob.average();
System.out.println("iob average is " + v);
Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Stats<Double> dob = new Stats<Double>(dnums);
double w = dob.average();
System.out.println("dob average is " + w);
// This won't compile because String is not a
// subclass of Number.
// String strs[] = { "1", "2", "3", "4", "5" };
// Stats<String> strob = new Stats<String>(strs);
// double x = strob.average();
// System.out.println("strob average is " + v);
}
}
class StatsWildCard<T extends Number> {
T[] nums; // array of Number or subclass
// Pass the constructor a reference to
// an array of type Number or subclass.
StatsWildCard(T[] o) {
nums = o;
}
// Return type double in all cases.
double average() {
double sum = 0.0;
for (int i = 0; i < nums.length; i++)
sum += nums[i].doubleValue();
return sum / nums.length;
}
// Determine if two averages are the same.
// Notice the use of the wildcard.
boolean sameAvg(StatsWildCard<?> ob) {
if (average() == ob.average())
return true;
return false;
}
}
public class GenericsExampleByWildcard {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Integer inums[] = { 1, 2, 3, 4, 5 };
StatsWildCard<Integer> iob = new StatsWildCard<Integer>(inums);
double v = iob.average();
System.out.println("iob average is " + v);
Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
StatsWildCard<Double> dob = new StatsWildCard<Double>(dnums);
double w = dob.average();
System.out.println("dob average is " + w);
Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F };
StatsWildCard<Float> fob = new StatsWildCard<Float>(fnums);
double x = fob.average();
System.out.println("fob average is " + x);
// See which arrays have same average.
System.out.print("Averages of iob and dob ");
if (iob.sameAvg(dob))
System.out.println("are the same.");
else
System.out.println("differ.");
System.out.print("Averages of iob and fob ");
if (iob.sameAvg(fob))
System.out.println("are the same.");
else
System.out.println("differ.");
}
}
class TwoD {
int x, y;
TwoD(int a, int b) {
x = a;
y = b;
}
}
// Three-dimensional coordinates.
class ThreeD extends TwoD {
int z;
ThreeD(int a, int b, int c) {
super(a, b);
z = c;
}
}
// Four-dimensional coordinates.
class FourD extends ThreeD {
int t;
FourD(int a, int b, int c, int d) {
super(a, b, c);
t = d;
}
}
// This class holds an array of coordinate objects.
class Coords<T extends TwoD> {
T[] coords;
Coords(T[] o) { coords = o; }
}
// Demonstrate a bounded wildcard.
public class BoundedWildcard {
static void showXY(Coords<?> c) {
System.out.println("X Y Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y);
System.out.println();
}
static void showXYZ(Coords<? extends ThreeD> c) {
System.out.println("X Y Z Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y + " " +
c.coords[i].z);
System.out.println();
}
static void showAll(Coords<? extends FourD> c) {
System.out.println("X Y Z T Coordinates:");
for(int i=0; i < c.coords.length; i++)
System.out.println(c.coords[i].x + " " +
c.coords[i].y + " " +
c.coords[i].z + " " +
c.coords[i].t);
System.out.println();
}
public static void main(String args[]) {
TwoD td[] = {
new TwoD(0, 0),
new TwoD(7, 9),
new TwoD(18, 4),
new TwoD(-1, -23)
};
Coords<TwoD> tdlocs = new Coords<TwoD>(td);
System.out.println("Contents of tdlocs.");
showXY(tdlocs); // OK, is a TwoD
// showXYZ(tdlocs); // Error, not a ThreeD
// showAll(tdlocs); // Erorr, not a FourD
// Now, create some FourD objects.
FourD fd[] = {
new FourD(1, 2, 3, 4),
new FourD(6, 8, 14, 8),
new FourD(22, 9, 4, 9),
new FourD(3, -2, -23, 17)
};
Coords<FourD> fdlocs = new Coords<FourD>(fd);
System.out.println("Contents of fdlocs.");
// These are all OK.
showXY(fdlocs);
showXYZ(fdlocs);
showAll(fdlocs);
}
}
public class ArrayListGenericDemo {
public static void main(String[] args) {
ArrayList<String> data = new ArrayList<String>();
data.add("hello");
data.add("goodbye");
// data.add(new Date()); This won't compile!
Iterator<String> it = data.iterator();
while (it.hasNext()) {
String s = it.next();
System.out.println(s);
}
}
}
public class HashDemoGeneric {
public static void main(String[] args) {
HashMap<Integer,String> map = new HashMap<Integer,String>();
map.put(1, "Ian");
map.put(42, "Scott");
map.put(123, "Somebody else");
String name = map.get(42);
System.out.println(name);
}
}
interface MinMax<T extends Comparable<T>> {
T min();
T max();
}
// Now, implement MinMax
class MyClass<T extends Comparable<T>> implements MinMax<T> {
T[] vals;
MyClass(T[] o) { vals = o; }
// Return the minimum value in vals.
public T min() {
T v = vals[0];
for(int i=1; i < vals.length; i++)
if(vals[i].compareTo(v) < 0) v = vals[i];
return v;
}
// Return the maximum value in vals.
public T max() {
T v = vals[0];
for(int i=1; i < vals.length; i++)
if(vals[i].compareTo(v) > 0) v = vals[i];
return v;
}
}
public class GenIFDemo {
public static void main(String args[]) {
Integer inums[] = {3, 6, 2, 8, 6 };
Character chs[] = {'b', 'r', 'p', 'w' };
MyClass<Integer> iob = new MyClass<Integer>(inums);
MyClass<Character> cob = new MyClass<Character>(chs);
System.out.println("Max value in inums: " + iob.max());
System.out.println("Min value in inums: " + iob.min());
System.out.println("Max value in chs: " + cob.max());
System.out.println("Min value in chs: " + cob.min());
}
}
interface Executor<E extends Exception> {
void execute() throws E;
}
public class GenericExceptionTest {
public static void main(String args[]) {
try {
Executor<IOException> e =
new Executor<IOException>() {
public void execute() throws IOException
{
// code here that may throw an
// IOException or a subtype of
// IOException
}
};
e.execute();
} catch(IOException ioe) {
System.out.println("IOException: " + ioe);
ioe.printStackTrace();
}
}
}
首先Q我们有必要从一个例子说?/span>
assert
public class AssertTest
{
public static void main(String[] args)
{
AssertTest at = new AssertTest();
at.assertMe(true);
at.assertMe(false);
}
private void assertMe(boolean boo)
{
assert boo?true:false;
System.out.println(true condition);
}
}
E序中包含了
assert
的话Q你要用
javac -source 1.4 xxx.java
来编译,否则~译器会报错的。要惌
assert
得部分运行的话,要?/span>
java -ea xxx
来运行,否则包含
assert
得行会被忽略。下面我们运?/span>
javac -source 1.4 AssertTest.java
java -ea AssertTest
看看l果的输出是Q?/span>
true condition
Exception in thread main java.lang.AssertionError
at AssertTest.assertMe(AssertTest.java:13)
at AssertTest.main(AssertTest.java:7)
当我们运?/span>
at.assertMe(true)
得时候,׃
assert boo?true:false
相当?/span>
assert true;
因此没有M问题Q程序往下执行打印出
true condition
Q但是执?/span>
at.assertMe(false)
的时候相当于
assert false
Q这个时候解释器׃抛出
AssertionError
了,E序q止了。大家必L?/span>
AssertionError
是承自
Error
得,因此你可以不再程序中
catch
它的Q当然你也可以在E序?/span>
catch
它然后程序可以l执行。例如:
public class AssertTest
{
public static void main(String[] args)
{
AssertTest at = new AssertTest();
try
{
at.assertMe(true);
at.assertMe(false);
}
catch(AssertionError ae)
{
System.out.println(AsseriontError catched);
}
System.out.println(go on);
}
private void assertMe(boolean boo)
{
assert boo?true:false;
System.out.println(true condition);
}
}
assert
q有另外一U表辄方式Q就?/span>
assert exp1:exp2;
其中
exp1
是个
boolean
q回值得表达式,?/span>
exp2
可以是原始的数据cd或者对象都可以例如Q?/span>
boolean boo = true;
String str = null;
assert boo = false
Q?/span>
str=error;
我们刚开始讲?/span>
assert exp1
得Ş式,?/span>
exp1
?/span>
false
得时候,
AssertionError
得默认构造器会被调用Q但?/span>
assert exp1:exp2
q样的Ş式,?/span>
exp1
?/span>
true
的时候后?/span>
exp2
被或略,如果
false
的话Q后面的表达式的l果会被计算出来q作?/span>
AssertionError
得构造器参数。看下面的例子:
public class AssertTest
{
public static void main(String[] args)
{
AssertTest at = new AssertTest();
at.assertMe(true);
at.assertMe(false);
}
private void assertMe(boolean boo)
{
String s = null;
assert boo?true:false:s = hello world;
System.out.println(true condition);
}
}
q行的时候会得到q样的结?/span>
true condition
Exception in thread main java.lang.AssertionError: hello world
at AssertTest.assertMe(AssertTest.java:14)
at AssertTest.main(AssertTest.java:7)
Assert
最好不要滥用,原因?/span>
assert
q不一定都?/span>
enable
的,下面两种情况׃应该?/span>
assert
1
不要?/span>
public
的方法里面检查参数是不是?/span>
null
之类的操?/span>
例如
public int get(String s)
{
assert s != null;
}
如果需要检查也最好通过
if s = null
抛出
NullPointerException
来检?/span>
2
不要?/span>
assert
来检查方法操作的q回值来判断Ҏ操作的结?/span>
例如
assert list.removeAll();
q样看v来好像没有问?/span>
但是x如果
assert
?/span>
disable
呢,那样他就不会被执行了
所?/span>
removeAll()
操作没有被执行
可以q样代替
boolean boo = list.removeAl();
assert boo;
以上是《effective java》中的论q。下面是在网上找到的关于匿名cȝ叙述?/font>
匿名c?br /> 匿名cL不能有名U的c,所以没办法引用它们。必d创徏Ӟ作ؓnew语句的一部分来声明它们。这p采用另一UŞ式的new语句Q如下所C:
new <cL接口> <cȝM>
q种形式的new语句声明一个新的匿名类Q它对一个给定的c进行扩展,或者实C个给定的接口。它q创建那个类的一个新实例Qƈ把它作ؓ语句的结果而返回。要扩展的类和要实现的接口是new语句的操作数Q后跟匿名类的主体?br /> 如果匿名cd另一个类q行扩展Q它的主体可以访问类的成员、覆盖它的方法等{,q和其他M标准的类都是一L。如果匿名类实现了一个接口,它的M必须实现接口的方法?br /> 注意匿名cȝ声明是在~译时进行的Q实例化在运行时q行。这意味着for循环中的一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例?br /> 从技术上_匿名cd被视为非静态的内部c,所以它们具有和Ҏ内部声明的非静态内部类一L权限和限制?br /> 如果要执行的d需要一个对象,但却不值得创徏全新的对象(原因可能是所需的类q于单,或者是׃它只在一个方法内部用)Q匿名类显得非常有用。匿名类其适合在Swing应用E序中快速创Z件处理程序?/font>
public interface Singer{
AudioClip Sing(Song s);
}
public interface Songwriter{
Song compose(boolean hit);
}
public interface SingerSongwriter extends Singer,Songwriter{
AudioClip strum();
void actSensitive();
}