您的位置:首页 > 编程语言 > Java开发

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

注意:设置私有访问权限。参数的传递。

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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: