java 获取type_java-Type的获取方式

https://www.jianshu.com/p/ac1b6dd211d0

这篇介绍了Type的分类,通常我们需要通过Class的类型或者变量的类型来获取Type

下面我们来看几个例子

1 通过Class获取Type

其本身就是一个Type类型

还有2个方法

getSuperclass和getGenericSuperclass,

如果是泛型类的话,2者会有区别,否则是一致的.

如果要获取参数化类型的话Class的getGenericSuperclass方法用的场景会比较多

public class TypeTest {

class Person {

}

class Student extends Person {

}

@Test

public void test1()

{

System.out.println("Student.class.getSuperclass()\t"

+ Student.class.getSuperclass());

System.out.println("Student.class.getGenericSuperclass()\t"

+ Student.class.getGenericSuperclass());

System.out.println("Test.class.getSuperclass()\t"

+ TypeTest.class.getSuperclass());

System.out.println("Test.class.getGenericSuperclass()\t"

+ TypeTest.class.getGenericSuperclass());

System.out.println("Object.class.getGenericSuperclass()\t"

+ Object.class.getGenericSuperclass());

System.out.println("Object.class.getSuperclass()\t"

+ Object.class.getSuperclass());

System.out.println("void.class.getSuperclass()\t"

+ void.class.getSuperclass());

System.out.println("void.class.getGenericSuperclass()\t"

+ void.class.getGenericSuperclass());

System.out.println("int[].class.getSuperclass()\t"

+ int[].class.getSuperclass());

System.out.println("int[].class.getGenericSuperclass()\t"

+ int[].class.getGenericSuperclass());

}

}

结果输出:

Student.class.getSuperclass() class demo.base.reflect.type.TypeTest$Person

Student.class.getGenericSuperclass() demo.base.reflect.type.TypeTest.demo.base.reflect.type.TypeTest$Person

Test.class.getSuperclass() class java.lang.Object

Test.class.getGenericSuperclass() class java.lang.Object

Object.class.getGenericSuperclass() null

Object.class.getSuperclass() null

void.class.getSuperclass() null

void.class.getGenericSuperclass() null

int[].class.getSuperclass() class java.lang.Object

int[].class.getGenericSuperclass() class java.lang.Object

2 通过Field获取Type

getType和getGenericType方法

public class FieldTest {

class Person {

public List charSequenceList;

public String str;

}

class Student extends Person {

}

@Test

public void test1() throws NoSuchFieldException {

{

Field field=Student.class.getField("str");

System.out.println(field.getType());

System.out.println(field.getGenericType());

}

{

Field field=Student.class.getField("charSequenceList");

System.out.println(field.getType());

System.out.println(field.getGenericType());

}

}

}

输出:

class java.lang.String

class java.lang.String

interface java.util.List

java.util.List

3 通过Method获取参数Type

Method是获取其参数或者返回值的Type,还有一个特殊的构造函数也可以归类为Method

public class MethodTest {

static class Person {

}

static class Student extends Person {

public Student(List list)

{

}

public Integer test(List list)

{

return null;

}

}

@Test

public void test1() throws NoSuchMethodException {

{

Method method=Student.class.getMethod("test",List.class);

Class type1=method.getParameterTypes()[0];

Type type2=method.getGenericParameterTypes()[0];

System.out.println(type1);

System.out.println(type2);

}

{

Constructor constructor=Student.class.getConstructor(List.class);

Class type1=constructor.getParameterTypes()[0];

Type type2=constructor.getGenericParameterTypes()[0];

System.out.println(type1);

System.out.println(type2);

}

}

}

4 MethodParameter

Spring对方法的参数做了一个抽象封装,如参数和返回值都可以认为是一个MethodParameter

可以使用MethodParameter.forMethodOrConstructor静态方法来构建一个MethodParameter

public class MethodParameterTests {

public static class TestItem

{

public TestItem(List list)

{

}

public void m1(List intParam)

{

}

}

@Test

public void test() throws NoSuchMethodException {

{

Method method=TestItem.class.getMethod("m1",List.class);

MethodParameter parameter=MethodParameter.forMethodOrConstructor(method,0);

System.out.println(parameter.getParameterType());

System.out.println(parameter.getGenericParameterType());

}

{

Constructor constructor=TestItem.class.getConstructor(List.class);

MethodParameter parameter=MethodParameter.forMethodOrConstructor(constructor,0);

System.out.println(parameter.getParameterType());

System.out.println(parameter.getGenericParameterType());

}

}

}

通过以上,已经了解到获取Type的几种场景

Class

Field字段

Method参数

Constructor参数

总结一下:需求是要获取Type和GenericType,但每个对象获取方法并不一致,怎么办?

需要做一个适配器,Spring中的ResolvableType就是来解决这个问题的.

ResolvableType可以传入上面任何参数,然后定义了公共的方法来统一方法规范调用,简化了获取Type的成本

比如MethodParameter已经对Method和Constructor做了一个整合,ResolvableType则对上面整体都做了一个整合

Java可以通过JDK中的Java Native Interface(JNI)调用操作系统的API来获取U盘的插拔事件,从而实现对U盘的监听。下面是一个简单的示例代码,演示了如何在Java中监听U盘的插拔事件: ```java import java.io.File; import java.util.Arrays; public class USBListener { static { System.loadLibrary("USBListener"); } public static native void start(); public static void main(String[] args) { USBListener.start(); } public static void onUSBInserted(String drivePath) { System.out.println("U盘已插入:" + drivePath); } public static void onUSBRemoved(String drivePath) { System.out.println("U盘已拔出:" + drivePath); } } ``` 上述代码中,我们定义了一个`USBListener`类,其中包含了一个`start()`方法,用于启动U盘监听功能。在`start()`方法中,我们通过JNI调用了一个名为`startUSBListener()`的C++函数,该函数启动了一个线程,循环遍历系统中的所有驱动器,并检查它们是否是可移动设备。如果是可移动设备,则将其保存到一个列表中,并且在后续的循环中持续检查它们是否被插拔。 当U盘被插入或拔出时,`startUSBListener()`函数会调用`onUSBInserted()`或`onUSBRemoved()`方法,这两个方法都是Java中的静态方法,可以在任何地方被调用。在本例中,我们只是简单地打印了一条消息,表示U盘已经插入或拔出了。 我们还需要在C++中实现`startUSBListener()`函数的代码,这里我们使用了Windows API来获取系统中的驱动器列表,并检查它们是否是可移动设备。以下是`startUSBListener()`函数的C++实现代码: ```cpp #include <Windows.h> #include <stdio.h> #include <stdlib.h> #include "USBListener.h" #define MAX_DRIVES 26 void startUSBListener(JNIEnv *env, jclass cls) { DWORD drives = GetLogicalDrives(); char driveLetter[] = "A:\\"; for (int i = 0; i < MAX_DRIVES; i++) { if ((drives & (1 << i)) != 0) { driveLetter[0] = 'A' + i; UINT type = GetDriveType(driveLetter); if (type == DRIVE_REMOVABLE) { HANDLE hDevice = CreateFile(driveLetter, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice != INVALID_HANDLE_VALUE) { char buf[MAX_PATH]; DWORD len; if (DeviceIoControl(hDevice, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &buf, sizeof(buf), &len, NULL)) { STORAGE_DEVICE_NUMBER *number = (STORAGE_DEVICE_NUMBER *) &buf; char drivePath[MAX_PATH]; sprintf(drivePath, "\\\\.\\PhysicalDrive%d", number->DeviceNumber); HANDLE hDrive = CreateFile(drivePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDrive != INVALID_HANDLE_VALUE) { OVERLAPPED overlapped = {}; char buffer[512]; DWORD bytesReturned; if (DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &buf, sizeof(buf), &len, &overlapped)) { while (1) { Sleep(1000); if (DeviceIoControl(hDrive, IOCTL_STORAGE_CHECK_VERIFY2, NULL, 0, NULL, 0, &bytesReturned, &overlapped)) { USBListener::onUSBRemoved(driveLetter); break; } else { if (GetLastError() == ERROR_NOT_READY) { USBListener::onUSBInserted(driveLetter); break; } } } } CloseHandle(hDrive); } } CloseHandle(hDevice); } } } } } ``` 在上述代码中,我们首先调用`GetLogicalDrives()`函数获取系统中所有的驱动器列表,然后遍历这个列表,并检查每个驱动器是否是可移动设备。如果是可移动设备,则使用`CreateFile()`函数打开该设备,并获取其设备号。然后,我们将设备号作为参数,使用`CreateFile()`函数打开该设备对应的物理驱动器,并调用`DeviceIoControl()`函数发送`IOCTL_STORAGE_CHECK_VERIFY2`控制码,以检查该U盘是否已经被插入或拔出。 如果`DeviceIoControl()`函数返回了`ERROR_NOT_READY`错误码,则表示该U盘已经被拔出,我们就调用`USBListener::onUSBRemoved()`方法通知Java代码;如果`DeviceIoControl()`函数成功返回,则表示该U盘已经被插入,我们就调用`USBListener::onUSBInserted()`方法通知Java代码。在检测到U盘被插入或拔出后,我们需要使用`Sleep()`函数等待一段时间,以避免频繁地检查设备状态导致CPU占用过高。 最后,我们需要使用JNI将C++代码编译成动态链接库,以供Java代码调用。以下是`USBListener.h`文件的内容: ```cpp #include <jni.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT void JNICALL Java_USBListener_startUSBListener(JNIEnv *, jclass); #ifdef __cplusplus } #endif ``` 然后,我们需要使用C++编译器将上述代码编译成动态链接库,以供Java代码调用。在Windows下,可以使用MinGW或Visual C++等编译器来编译,例如: ```bash g++ -shared -o USBListener.dll -I"C:\Program Files\Java\jdk1.8.0_231\include" -I"C:\Program Files\Java\jdk1.8.0_231\include\win32" USBListener.cpp ``` 编译完成后,我们就可以在Java代码中使用`System.loadLibrary()`方法加载该动态链接库,并调用`USBListener.start()`方法启动U盘监听功能了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值