java反射常用方法

合集下载

java使用反射调用可变参数方法

java使用反射调用可变参数方法

java使⽤反射调⽤可变参数⽅法使⽤反射操作对象-调⽤可变参数⽅法要把可变参数都当做是其对应的数组类型参数;如 show(XX... is)作为show(XX[] is)调⽤;若可变参数元素类型是引⽤类型:JDK内部接收到参数之后,会⾃动拆包取出参数再分配给该底层⽅法,为此我们需要把这个数组实参先包装成⼀个Object对象或把实际参数作为⼀个Object⼀维数组的元素再传递。

若可变参数元素类型是基本类型:JDK内部接收到参数之后,不会拆包,所以可以不必再封装.不过封装了也不会错.所以建议,不管基本类型还是引⽤类型都使⽤Object[]封装⼀层,保证⽆误.例⼦package junereflect624;//可变参数的⽅法调⽤import ng.reflect.Method;class VaryMethod{public static void show(int ...args){System.out.println("基本数据类型传递过来了!");}/*public static void show(int[] args){//这是⼀样的}*/public static void show(String ...args){System.out.println("引⽤数据类型传递过来了!");}}public class InvokeVaryDemo10 {public static void main(String[] args) throws Exception{Class<VaryMethod> c = VaryMethod.class;Method m = c.getMethod("show",int[].class);m.invoke(null,new int[]{1,2,3});m = c.getMethod("show",String[].class);//m.invoke(null,new String[]{"A","B","C"});//ERRORm.invoke(null,(Object)new String[]{"A","B","C"});//YES,强转为Object类型 m.invoke(null,new Object[]{new String[]{"A","B","C"}});//推荐写法}}。

Java反射,获取类的公有、私有的构造函数(有参,无参)、方法(有参,无参)、属性

Java反射,获取类的公有、私有的构造函数(有参,无参)、方法(有参,无参)、属性

Java反射,获取类的公有、私有的构造函数(有参,⽆参)、⽅法(有参,⽆参)、属性Class类与ng.reflect类库⼀起对反射进⾏了⽀持,该类库包含Field、Method和Constructor类,这些类的对象由JVM在启动时创建,⽤以表⽰未知类⾥对应的成员。

这样的话就可以使⽤Contructor创建新的对象,⽤get()和set()⽅法获取和修改类中与Field对象关联的字段,⽤invoke()⽅法调⽤与Method对象关联的⽅法。

另外,还可以调⽤getFields()、getMethods()和getConstructors()等许多便利的⽅法,以返回表⽰字段、⽅法、以及构造器对象的数组,这样,对象信息可以在运⾏时被完全确定下来,⽽在编译时不需要知道关于类的任何事情。

⾸先创建⼀个类1public class Per {2public String name="sunshine";3private int age=28;4public double weight=65.50;56public Per(){7 System.out.println("测试反射获取公有⽆参构造函数");8 }9private Per(String name){=name;11 System.out.println("测试反射获取私有有参构造函数");12 }13public Per(String name,int age){=name;15this.age=age;16 System.out.println("测试反射获取公有有多个参数构造函数name:"+name+" age:"+age);17 }18public String methodT1(){19 System.out.println("测试反射获取公有⽆参⽅法");20return null;21 }22public String methodT1(String name,int age){23 System.out.println("测试反射获取公有多个参⽅法");24 System.out.println(name+":"+age);25return null;26 }27private String methodT1(String name){28 System.out.println("测试反射获取私有有参⽅法");29 System.out.println("name:"+name);30return null;31 }32public String methodT2(int[] arr,String[] str){33 System.out.println("测试反射获取公有有数组参⽅法");34 System.out.println("int[] arr:"+arr+"String[] str:"+str);35return null;36 }37public static void main(String[] args) {38 System.out.println("测试反射获取main⽅法");39 }40 }1.使⽤java反射获取类的构造函数(公有、私有)(有参,⽆参)1import ng.reflect.Constructor;2import ng.reflect.Field;3import ng.reflect.Method;45import org.junit.AfterClass;6import org.junit.BeforeClass;7import org.junit.Test;8/**9 * 测试使⽤java反射获取类的构造函数并创建对象10 * @author Sunshine11 *12*/13public class ReflectPer {14private static Class class1;15//因为java反射获取类时都需要加载类,在这⾥我就使⽤Junit的@beforeclass来去加载类,不⽤在每个测试⽅法中重复创建16//注:@beforeclass在执⾏测试⽅法前运⾏17 @BeforeClass18public static void beforeClass() throws Exception{19 System.out.println("====测试⽅法启动前先加载类====");20 class1 = Class.forName("myPractise.Per");//加载类21 }22//获取类的公有⽆参构造函数,并创建对象23 @Test24public void test1() throws Exception{25 Constructor constructor = class1.getConstructor(null);//获取公有⽆参构造器,值为null代表获取⽆参构造器26 Per per = (Per) constructor.newInstance(null);//创建对象,返回的是Object类型要强转27 System.out.println();//可以调⽤类的属性-----成功28 }29//获取类的公有参构造函数,并创建对象30 @Test31public void test2()throws Exception{32 Constructor constructor = class1.getConstructor(String.class,int.class);//获取公有多个参数构造器,参数为构造器中参数的类型33 Per per = (Per)constructor.newInstance("baby",24);//创建对象34 }35//获取类的私有有参构造函数,并创建对象36 @Test37public void test3()throws Exception{38 Constructor constructor = class1.getDeclaredConstructor(String.class);//获取公有多个参数构造器,参数为构造器中参数的类型39 constructor.setAccessible(true);//暴⼒反射,只有将属性设置为true才可以创建对象40 Per per = (Per)constructor.newInstance("baby");41 System.out.println(per.weight);//可以调⽤类的属性-----成功42//注:通常情况下⼀个类不可以访问另⼀个类的私有的属性,⽅法。

深入解析Java反射-invoke方法

深入解析Java反射-invoke方法

深⼊解析Java反射-invoke⽅法上篇⽂章中回顾了⼀下Java反射相关的基础内容。

这⼀节我们来深⼊研究Method类中的invoke⽅法,探寻它的奥秘。

注:本篇⽂章的所有源码都基于OpenJDK 1.8。

引⼊即使没有学过反射,⼤家也⼀定会见过invoke⽅法。

因为很多⽅法调⽤都是靠invoke⽅法,所以很多异常的抛出都会定位到invoke⽅法,⽐如下⾯的情形⼤家会很熟悉:1 2 3 4 5 ng.NullPointerExceptionat ......at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at ng.reflect.Method.invoke(Method.java:497)⼤家在看到异常抛出时,除了想要排除Bug,是不是同时也对这个神秘的invoke乃⾄invoke0⽅法有⼀些好奇呢?我们下⾯就来揭开它神秘的⾯纱,探寻底层的机制。

浅析invoke过程上⼀篇⽂章我们讲过,invoke⽅法⽤来在运⾏时动态地调⽤某个实例的⽅法。

它的实现如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17@CallerSensitivepublic Object invoke(Object obj, Object... args)throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{if (!override) {if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { Class<?> caller = Reflection.getCallerClass(); checkAccess(caller, clazz, obj, modifiers);}}MethodAccessor ma = methodAccessor; // read volatileif (ma == null) {ma = acquireMethodAccessor();}return ma.invoke(obj, args);}我们根据invoke⽅法的实现,将其分为以下⼏步:1、权限检查invoke⽅法会⾸先检查AccessibleObject的override属性的值。

Java反射(Class类,Class对象获取)

Java反射(Class类,Class对象获取)

Java反射(Class类,Class对象获取)⽬录Java反射超详解1.反射基础1.1Class类1.2类加载2.反射的使⽤2.1Class对象的获取2.2Constructor类及其⽤法2.3Field类及其⽤法Java反射超详解1.反射基础Java反射机制是在程序的运⾏过程中,对于任何⼀个类,都能够知道它的所有属性和⽅法;对于任意⼀个对象,都能够知道它的任意属性和⽅法,这种动态获取信息以及动态调⽤对象⽅法的功能称为Java语⾔的反射机制。

Java反射机制主要提供以下这⼏个功能:在运⾏时判断任意⼀个对象所属的类在运⾏时构造任意⼀个类的对象在运⾏时判断任意⼀个类所有的成员变量和⽅法在运⾏时调⽤任意⼀个对象的⽅法1.1Class类Class类,Class类也是⼀个实实在在的类,存在于JDK的ng包中。

Class类的实例表⽰java应⽤运⾏时的类(class ans enum)或接⼝(interface and annotation)(每个java类运⾏时都在JVM⾥表现为⼀个class对象,可通过类名.class、类型.getClass()、Class.forName("类名")等⽅法获取class对象)。

数组同样也被映射为为class 对象的⼀个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class 对象。

到这我们也就可以得出以下⼏点信息:Class类也是类的⼀种,与class关键字是不⼀样的。

⼿动编写的类被编译后会产⽣⼀个Class对象,其表⽰的是创建的类的类型信息,⽽且这个Class对象保存在同名.class的⽂件中(字节码⽂件)。

每个通过关键字class标识的类,在内存中有且只有⼀个与之对应的Class对象来描述其类型信息,⽆论创建多少个实例对象,其依据的都是⽤⼀个Class对象。

java 反射调用native方法

java 反射调用native方法

java 反射调用native方法什么是Java反射?Java反射是指在程序运行时动态地获取类的信息,并在运行时操作类或对象的一种机制。

通过Java反射,我们可以在运行时获取类、字段、方法、注解等的相关信息,并且可以在运行时动态地创建对象、调用方法和访问属性。

为什么需要使用Java反射?Java反射在某些情况下非常有用。

主要有以下几个方面的应用:1. 对于一些未知的类,我们可以通过反射来获取其信息,比如类的名称、属性、方法等。

在框架和类库的设计中,使用反射可以动态地获取类相关的信息,从而根据类的特征动态地执行相关操作。

2. 在某些情况下,我们需要动态地创建对象。

通过反射,我们可以在运行时根据类名来创建对象,而不需要事先知道具体的类名。

这使得程序更加灵活,能够适应不同的需求。

3. 反射可以使我们能够在运行时调用类的方法和访问类的属性。

这使得我们可以通过反射机制实现一些动态地、灵活地调用方法的功能。

4. 使用反射还可以实现一些Java类库中的功能,比如注解处理、序列化、动态代理等。

Java反射的基本用法下面我们来具体看一下Java反射的基本用法。

1. 获取Class对象在Java中,要使用反射,首先需要获取要操作的类的Class对象。

Class 对象是在JVM中表示类的元数据的一种对象,可以通过以下方法获取:(1)通过对象的getClass()方法获取,比如Object obj = new Object(); Class<?> cls = obj.getClass();(2)通过类名.class获取,比如Class<?> cls = Object.class;(3)通过Class.forName()方法获取,比如Class<?> cls =Class.forName("ng.Object");2. 获取类的信息通过Class对象,我们可以获取被操作类的各种信息,包括类名、字段信息、方法信息、构造函数等。

java反射获取field的类型

java反射获取field的类型

java反射获取field的类型Java反射是一种强大的机制,可以在运行时动态地获取和操作类的信息。

其中一个常见的应用就是获取Field的类型。

本文将介绍如何使用Java反射来获取Field的类型,并通过示例代码加深理解。

我们需要了解什么是Field。

在Java中,Field是类中的一个属性或变量。

通过Field,我们可以获取和修改类的成员变量的值。

在Java反射中,Field类代表一个类的成员变量,并提供了一系列方法来获取和操作该成员变量。

要获取Field的类型,我们首先需要获取对应的Class对象。

在Java反射中,Class类是对一个类的抽象,通过Class类可以获取类的各种信息,包括成员变量、方法、构造器等。

获取Class对象有多种方法,最常见的是使用类名的方式,例如`Class clazz = MyClass.class;`。

一旦有了Class对象,我们就可以通过它来获取Field对象。

Field 对象可以表示一个类的成员变量,包括私有和公有的成员变量。

在Field类中,有一个`getType()`方法可以获取Field的类型。

该方法返回一个Class对象,表示Field的类型。

下面是一个示例代码,演示了如何使用Java反射获取Field的类型:```javaimport ng.reflect.Field;public class ReflectDemo {private String name;public int age;public static void main(String[] args) {ReflectDemo obj = new ReflectDemo();Class clazz = obj.getClass();Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {Class fieldType = field.getType();System.out.println("Field: " + field.getName() + ", Type: " + fieldType.getName());}}}```在上面的代码中,我们首先创建了一个ReflectDemo对象,并获取了它的Class对象。

java反射获取service方法

java反射获取service方法

java反射获取service方法Java中的反射机制可以用来获取Service方法。

Service方法是一种用于在Android应用程序中执行后台任务的组件。

反射机制可以让开发者在运行时获取和操作类、方法、字段等信息,从而实现更加灵活的编程。

下面介绍如何使用Java反射获取Service方法。

首先,通过反射获取Service对象。

可以使用如下代码:```javaClass<?> serviceClass =Class.forName('com.example.MyService');Intent intent = new Intent(context, serviceClass);IBinder binder = bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);MyService myService = ((MyService.LocalBinder) binder).getService();```其中,'com.example.MyService'是Service类的完整路径名,context是应用程序的上下文。

接下来,可以使用Java反射机制获取Service类中的方法。

可以使用如下代码:```javaClass<?> serviceClass = myService.getClass();Method[] methods = serviceClass.getDeclaredMethods();```这段代码会获取Service类中的所有方法,包括私有方法和继承的方法。

如果只需要获取指定名称的方法,可以使用如下代码:```javaClass<?>[] paramTypes = new Class<?>[]{String.class, int.class};Method method =serviceClass.getDeclaredMethod('myMethod', paramTypes);```其中,'myMethod'是需要获取的方法名称,paramTypes是方法参数类型的Class对象数组。

java反射setaccessible替代方法

java反射setaccessible替代方法

在Java中,setAccessible(true) 是通过反射机制取消访问检查的常见方法。

然而,如果您不想使用setAccessible(true),有其他替代方法来实现类似的功能,尤其是在访问私有成员时。

以下是一些替代方法:1. 使用公共方法或构造函数如果可能的话,最好的方式是通过类的公共方法或构造函数来访问私有成员。

这样就避免了直接访问私有成员,而是通过类提供的公共接口来进行操作。

2. 使用Getter和Setter方法在类中定义公共的Getter和Setter方法,通过这些方法来访问私有成员变量。

这是一种良好的封装实践,可以保持对成员的控制同时提供访问的方式。

public class MyClass {private int privateField;public int getPrivateField() {return privateField;}public void setPrivateField(int value) {this.privateField = value;}}3. 使用构造函数或工厂方法可以通过构造函数或者静态工厂方法来创建类的实例,并在这些方法中设置私有成员变量的值。

public class MyClass {private int privateField;private MyClass(int privateField) {this.privateField = privateField;}public static MyClass createInstance(int privateField) {return new MyClass(privateField);}}4. 使用MethodHandlesJava 7 引入了ng.invoke.MethodHandles,它提供了一种更安全的方式来处理反射操作,而无需使用setAccessible(true)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

java反射常用方法
Java反射是指在程序运行时,通过调用Java API中的反射对象对程序中的类、接口、方法等进行操作和访问。

Java反射可以使得我们在运行时动态地获取程序的信息,而不需要在编码时硬编码的方式进行访问。

在Java反射中,一些常用的方法包括:
1. 获取Class对象
在Java中,每个类都有一个与之对应的Class对象,可以通过Class类的静态方法forName()或者使用类名.class获取。

例如:
```
Class<?> clazz1 = Class.forName("ng.String");
Class<?> clazz2 = String.class;
```
2. 获取构造方法
通过Class对象获取一个类的构造方法,可以通过Class类的getConstructor()和getConstructors()方法获取。

例如:
```
Constructor<?> constructor1 = clazz.getConstructor(String.class, int.class);
Constructor<?>[] constructors = clazz.getConstructors();
```
3. 获取字段
获取一个类的字段可以通过Class类的getField()和getDeclaredField()方法来实现,前者只能获取公共字段,而后者可以获取所有字段,包括私有字段。

例如:
```
Field field1 = clazz.getField("name");
Field field2 = clazz.getDeclaredField("age");
```
4. 获取方法
通过Class对象获取一个类的方法可以通过Class类的getMethod()和getDeclaredMethod()方法来实现,前者只能获取公共方法,而后者可以获取所有方法,包括私有方法。

例如:
```
Method method1 = clazz.getMethod("toString");
Method method2 = clazz.getDeclaredMethod("setName", String.class);
```
5. 调用方法
在获取到方法对象之后,可以通过invoke()方法来调用该方法。

例如:
```
method1.invoke(object);
method2.invoke(object, "Tom");
```
6. 获取注解
反射还可以用来获取类和方法上的注解信息,可以通过Class对象的getAnnotation()方法获取类上的注解信息,通过Method对象的getAnnotation()方法获取方法上的注解信息。

例如:
```
MyAnnotation annotation1 = clazz.getAnnotation(MyAnnotation.class);
MyAnnotation annotation2 = method.getAnnotation(MyAnnotation.class);
```
以上是Java反射的一些常用方法,通过这些方法,可以在程序运行时动态地获取程序的信息,从而实现更加灵活的编程方式。

需要注意的是,反射虽然提供了便利,但是由于反射操作会降低程序的性能,因此在编写程序时应该尽量避免过多地使用反射。

相关文档
最新文档