Java反射&JNI[Java Native Interface](5.28)

本文介绍了如何在Linux环境下安装Java JDK,并详细讲述了配置环境变量的步骤,包括下载JDK、添加可执行权限、编辑bash.bashrc文件以及测试环境变量的设置。此外,还提到了Java反射和JNI(Java Native Interface)中的静态注册步骤,强调了-Djava.library.path的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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(); 
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值