Java反射&JNI[Java Native Interface](5.28)
2015-05-28 20:01
330 查看
1.反射
[1]通过反射机制,用户程序员可以知道任意类里面的所有属性和方法(哪怕是私有的)。对于任意对象,可以调用它的任意属性和方法。
[2].class文件加载后,JVM会生成一个类对象。类对象中包含:类中的所有构造,属性,行为。
[3]反射相关类
类对象包含:Constructor对象,Field对象,Method对象
Constructor对象存放所有构造
File对象存放所有属性
Method对象存放所有的行为
[4]类对象
创建:JVM创建类对象,一个类有且只有一个类对象。
获取类对象的三种方式:1.通过类名获取
2.通过调用Class类中的静态方法获取
3.通过对象获取
通过类对象,反射出构造函数对象。getDeclaredConstructor
通过类对象,反射出成员属性。 getDeclaredField
通过类对象,反射出成员方法。 getDeclaredMethod
注意:设置私有访问权限。参数的传递。
2.JNI
Linux下安装jdk:
1.官网下载jdk
网址http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html
2.为jdk-6u27-linux-1586.bin添加可执行权限 chmod u+x jdk-6u27-linux-1586.bin
使用 ./jdk-6u27-linux-1586.bin安装
3.配置环境变量
cd /etc
sudo vi bash.bashrc 进入文件编辑模式,按i键就可以编辑了。 (注意进入之前,输入系统密码"1",权限最高,文件可读写)
在文件的最后一行添加:export PATH=$PATH:/home/ubuntu/java/jdk1.6.0_45/bin
保存文件并退出
执行命令:source bash.bashrc 环境变量立即生效
4.使用javac和java命令测试环境变量是否配置成功
静态注册步骤:
[1]创建包含本地方法的类。 MyJni.java
[2]javac 编译包含本地方的类 MyJni.java。生成MyJni.class
[3]执行命令:javah MyJni 使用Jni的字节码文件生成头文件MyJni.h
[4]实现头文件
创建出.c文件。实现头文件中的函数。
[5]生成.so文件 (生成动态链接库)
gcc -fPIC -I /jdk/include -I /jdk/include/linux -shared -o libMyJni.so MyJni.c
(注意生成动态库时,命名以lib开头,不然系统无法识别)
[6]创建测试类。Test.java
[7]编译 javac Test.java 生成 Test.class
[8]运行 java -Djava.library.path=. Test
运行类文件时,指定动态库的位置,告知JVM在哪里去加载访问动态库。
-Djava.library.path=. (.表示在当前目录下)
[1]通过反射机制,用户程序员可以知道任意类里面的所有属性和方法(哪怕是私有的)。对于任意对象,可以调用它的任意属性和方法。
[2].class文件加载后,JVM会生成一个类对象。类对象中包含:类中的所有构造,属性,行为。
[3]反射相关类
类对象包含:Constructor对象,Field对象,Method对象
Constructor对象存放所有构造
File对象存放所有属性
Method对象存放所有的行为
[4]类对象
创建:JVM创建类对象,一个类有且只有一个类对象。
获取类对象的三种方式:1.通过类名获取
2.通过调用Class类中的静态方法获取
3.通过对象获取
通过类对象,反射出构造函数对象。getDeclaredConstructor
通过类对象,反射出成员属性。 getDeclaredField
通过类对象,反射出成员方法。 getDeclaredMethod
注意:设置私有访问权限。参数的传递。
package com; public class Book { private String name; private int price; public Book() { // TODO Auto-generated constructor stub } public Book(String name, int price) { super(); this.name = name; this.price = price; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } private void print(){ System.out.println(name + ":" + price); } private void sell(int number){ System.out.println(name + "卖了" + number + "本"); } private void sell(int number, float d){ System.out.println(name + "卖了" + number + "本书,打了" + d + "折"); } }
package com; public class Single { // private static Single instance; private Single() { // TODO Auto-generated constructor stub } public static Single getInstance() { if(instance == null) { instance = new Single(); } return instance; } }
package com; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub //得到Book的类对象 try { Class a = Class.forName("com.Book"); //基本数据类型的类对象 Class ii = int.class; //反射出类对象book中所有声明的方法 System.out.println("反射出所有声明的方法"); Method methods[] = a.getDeclaredMethods(); for (int i = 0; i < methods.length; i++) { System.out.println(methods[i]); } System.out.println("反射出所有公共的方法,并且包含从父类继承下来的公共方法"); Method methodsPublic[] = a.getMethods(); for (int i = 0; i < methodsPublic.length; i++) { System.out.println(methodsPublic[i]); } //反射出Book中的私有方法 Method methodPrivate = a.getDeclaredMethod("print", null); //设置私有成员可访问权限 methodPrivate.setAccessible(true); Book book = new Book("think in java", 100); //调用book对象中的私有方法 methodPrivate.invoke(book); //反射私有方法sell(int) Method methodSell = a.getDeclaredMethod("sell", int.class, float.class); methodSell.setAccessible(true); methodSell.invoke(book, 10, 7.5f); //------反射出系统类 Thread //java.lang.Thread Class threadClass = Class.forName("java.lang.Thread"); Field fields[] = threadClass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { System.out.println(fields[i]); } Constructor[] constructors = threadClass.getDeclaredConstructors(); for (int i = 0; i < constructors.length; i++) { System.out.println(constructors[i]); } Method[] threadMethods = threadClass.getDeclaredMethods(); for (int i = 0; i < threadMethods.length; i++) { System.out.println(threadMethods[i]); } //取出指定的属性对象 Field fieldName = a.getDeclaredField("name"); //利用反射给私有属性赋值 System.out.println(book.getName()); fieldName.setAccessible(true); fieldName.set(book, "head first in java"); //得用反射机制取出私有属性值 System.out.println(fieldName.get(book)); //反射出私有构造 Class singleClass = Class.forName("com.Single"); Constructor con = singleClass.getDeclaredConstructor(null); con.setAccessible(true); //创建对象 Single single_01 = (Single)con.newInstance(); //创建对象 Single single_02 = (Single)con.newInstance(); System.out.println(single_01); System.out.println(single_02); //reflect 机制详解 jvm详解 } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchMethodException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (NoSuchFieldException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.JNI
Linux下安装jdk:
1.官网下载jdk
网址http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase6-419409.html
2.为jdk-6u27-linux-1586.bin添加可执行权限 chmod u+x jdk-6u27-linux-1586.bin
使用 ./jdk-6u27-linux-1586.bin安装
3.配置环境变量
cd /etc
sudo vi bash.bashrc 进入文件编辑模式,按i键就可以编辑了。 (注意进入之前,输入系统密码"1",权限最高,文件可读写)
在文件的最后一行添加:export PATH=$PATH:/home/ubuntu/java/jdk1.6.0_45/bin
保存文件并退出
执行命令:source bash.bashrc 环境变量立即生效
4.使用javac和java命令测试环境变量是否配置成功
静态注册步骤:
[1]创建包含本地方法的类。 MyJni.java
public class MyJni { public native void turnOn(); }
[2]javac 编译包含本地方的类 MyJni.java。生成MyJni.class
[3]执行命令:javah MyJni 使用Jni的字节码文件生成头文件MyJni.h
[4]实现头文件
创建出.c文件。实现头文件中的函数。
[5]生成.so文件 (生成动态链接库)
gcc -fPIC -I /jdk/include -I /jdk/include/linux -shared -o libMyJni.so MyJni.c
(注意生成动态库时,命名以lib开头,不然系统无法识别)
[6]创建测试类。Test.java
class Test { static { System.loadLibrary("MyJni"); } public static void main(String args[]) { MyJni myJni = new MyJni(); myJni.turnOn(); } }
[7]编译 javac Test.java 生成 Test.class
[8]运行 java -Djava.library.path=. Test
运行类文件时,指定动态库的位置,告知JVM在哪里去加载访问动态库。
-Djava.library.path=. (.表示在当前目录下)
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class MyJni */ #ifndef _Included_MyJni #define _Included_MyJni #ifdef __cplusplus extern "C" { #endif /* * Class: MyJni * Method: turnOn * Signature: ()V */ JNIEXPORT void JNICALL Java_MyJni_turnOn (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
#include "MyJni.h" /* * Class: MyJni * Method: turnOn * Signature: ()V */ JNIEXPORT void JNICALL Java_MyJni_turnOn(JNIEnv *env, jobject obj) { printf("turnOn light\n"); }
public class MyJni{ //本地方法,方法体交给c函数实现 //java调用本地方法时,系统会找到实现本地方法的c函数,运行。 public native void turnOn(); }
public class MyJniTest{ static{ System.loadLibrary("MyJni"); } public static void main(String args[]){ System.out.println("Hello Jni"); MyJni myJni = new MyJni(); //调用本地方法 myJni.turnOn(); } }
相关文章推荐
- Android C 直接調用JNI ->JAVA
- Java学习笔记23 反射机制(reflect…
- java 反射小应用 <模范eclipse里面的ctrl+o快捷键>
- JNI--java调用C&C++
- 2014.1.27 Java RTTI && 反射
- 关于JAVA中JNI的应用 <转>
- Java 面试题之反射的应用(如何在List<String> list = new ArrayList<String>();中放入Integer类型的数据)
- java native&JNI
- Java查看注册表错误:ERROR You have not installed the DLL named 'ICE_JNIRegistry.DLL'
- JNI中用 javah.exe 产生头JNI-Style文件出现错误:无法访问 <class> 未找到 <class> 的类文件
- RDD & java 类 (反射)构建 DataFrame ---java code
- 用反射属性类型为:java.util.List<com.abc.User>
- Android之jni编译出现no matching function for call to '_JNIEnv::GetJava(JNIEnv* &, Java VM**)'解决办法)'
- JAVA&JNI 数据类型
- Android NDK编译之undefined reference to 'JNI_CreateJavaVM'
- JNI 之二 :java & c/c++ 相互通信及调用
- Java学习笔记之<反射、内省、BeanUtils包操作JavaBean的对比>
- Java笔记7 Java基础加强<1>反射
- JNI 之二 :java & c/c++ 相互通信及调用
- 黑马程序员-反射 & JavaBean