利用java反射调用类的的私有方法
- 格式:doc
- 大小:53.50 KB
- 文档页数:3
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编程关键字: 开发反射私有因一时兴起看了一些有关 Java 反射( Reflection )的东西。
以下要说明的问题是如何直接对某个特定类的私有属性( private field )不使用其暴露的 set 方法而是直接进行设值操作,或调用类的私有方法( private method )。
首先要说明的是,这在 java 里是允许这么做的。
虽然这样直接访问私有属性或调用私有方法,会破坏了 OO 的一大基本原则:封装,但 Java 里是千真万确的提供了这么做的基础的。
一些 Open source framework 的“豪华”功能也是依赖于此的。
此前在网上看到不少兄弟提出过这样的问题,有人略带讽刺的回复说这样做是不可以的。
在这里不才给出一个简单的示例来说明如何完成的这个被看成 Mission Imposable 的。
首先我们建立一个测试用的类( TargetClass ):package org.rossalee.test;public class TargetClass {public String name ;private String age ;public TargetClass() {super ();}public void showName() {System. out .println( name );}private void showAge() {System. out .println( age );}}这个目标类里有一个 public 权限 String 类型“ name ”属性和一个 private 权限String 类型的“ age ”属性,以及一个 public 方法“ showName() ”和 private 方法“ showAge() ”。
一般来说我们是可以直接操作该类的 name 属性或调用 showName() 方法的。
Java通过反射访问及修改类内的私有变量 写mod的时候,界⾯某项功能显⽰定位需要⽤到玩家周围的boss信息,然⽽这个信息存储在⼀个私有的Map变量⾥,所在的类也没有提供get⽅法。
最后发现可以利⽤反射获取该私有变量的值。
以下是⽰例代码,其中field.setAccessible(true)最为重要。
import java.util.ArrayList;import ng.reflect.Field;public class Test {public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {TestClass testClass = new TestClass();// 获取TestClass对象的所有变量Field[] fields = testClass.getClass().getDeclaredFields();for (Field field : fields){// 设置为为true时可访问私有类型变量field.setAccessible(true);// 根据获取到的变量名输出变量值// 这⾥的get和set可能抛出IllegalAccessException异常switch(field.getName()){case "integer":System.out.println("integer:" + field.get(testClass));break;case "string":// 即使是final修饰的变量也能改变其值field.set(testClass, "new text");System.out.println("string:" + field.get(testClass));break;case "arrayList":@SuppressWarnings("unchecked")ArrayList<Double> arrayList = (ArrayList<Double>) field.get(testClass);arrayList.add(5.6);for(Double d : arrayList){System.out.println("arrayList:" + d);}}}// 也可以根据已知的变量名获取值,但是可能抛出NoSuchFieldException异常Field field = testClass.getClass().getDeclaredField("integer");field.setAccessible(true);field.set(testClass, 1);System.out.println("integer:" + field.get(testClass));}}class TestClass{public final int integer = 0;private final String string = "text";private final ArrayList<Double> arrayList = new ArrayList<>();public TestClass(){arrayList.add(1.2);arrayList.add(3.4);}}。
Java如何通过反射获取私有构造、私有对象、私有字段、私有⽅法Java反射获取私有构造、私有对象、私有字段、私有⽅法1. 创建测试的私有对象/*** @author lirong* @desc 测试对象* @date 2019/06/20 20:07*/public class Person {private int age = 5;private String name;private Person(){}private String test(String name){System.out.println("name: "+name);return "test";}}2. 获取私有对象中的属性和⽅法/*** @author lirong* @desc 反射获取私有属性和⽅法* @date 2019/06/20 20:10*/public class Test {public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException { // 1. 获取class对象Class clazz = Person.class;// 2. 获取私有⽆参构造Constructor c = clazz.getDeclaredConstructor();// 3. 设置访问为可见c.setAccessible(true);// 4. 通过构造器创建实例对象Person person = (Person) c.newInstance();// 根据字段名称获取class中的字段Field age = clazz.getDeclaredField("age");age.setAccessible(true);System.out.println(age.getName() + " = " + age.get(person));// 修改私有变量的默认值age.set(person, 18);System.out.println(age.getName() + " = " + age.get(person));// 5. 获取所有字段Field[] fields = clazz.getDeclaredFields();for (Field f : fields) {// 设置字段的可见性f.setAccessible(true);String name = f.getName();Object o = f.get(person);System.out.println(name + " - " + o);}// 6. 获取所有的⽅法Method[] methods = clazz.getDeclaredMethods();for (Method m : methods) {m.setAccessible(true);String name = m.getName();Object invoke = m.invoke(person, "张三");System.out.println(name + " = "+invoke);}}}通过反射获取私有内部类对象⾸先是我们的⽬标对象:class Out {//⽬标获取Inner对象private class Inner {//内部类的私有成员属性private String inner = "ccc";}}直接列出代码public class Main {@SuppressWarnings({ "rawtypes", "unchecked" })public static void main(String[] args) throws Exception {//获取外部类Class clzz = Out.class;//获取外部类默认⽆参构造⽅法Constructor con = clzz.getDeclaredConstructor();//实例⼀个外部类对象Out outObj = (Out) con.newInstance();//获取外部类内的所有内部类Class innerClazz[] = clzz.getDeclaredClasses();//遍历for (Class c : innerClazz) {//获取修饰符的整数编码int mod = c.getModifiers();//返回整数编码对应的修饰符的字符串对象String modifier = Modifier.toString(mod);//找到被private修饰的内部类if (modifier.contains("private")) {//根据内部类的特性,需要由外部类来反射获取内部类的构造⽅法(这⾥获取的是内部类的默认构造⽅法) Constructor cc = c.getDeclaredConstructor(clzz);//由于内部类是私有的,需要强制获取构造⽅法的访问权限cc.setAccessible(true);//由外部类对象来反射获取内部类的对象Object obj=cc.newInstance(outObj);//获取内部类的私有成员属性innerField f=c.getDeclaredField("inner");//获取访问权限f.setAccessible(true);//获取内部类对象obj中的私有成员属性inner的值System.out.println(f.get(obj));}}}}输出结果:ccc以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
一、反射的概念及用途在 Java 程序中,反射是一种强大的功能,它允许程序在运行时动态地加载、检查、修改类、方法、属性等结构,并对其进行操作。
使用反射,程序可以获取类的信息,调用类的方法,获取和设置类的属性等。
这为程序的设计和开发提供了更大的灵活性和可扩展性。
二、反射的基本操作在 Java 中,反射主要通过 ng.reflect 包中的类和接口来进行操作。
其中,主要涉及的类和接口包括:1. Class 类:代表类的实例,在运行时提供类的信息。
2. Method 类:代表类的方法。
3. Field 类:代表类的属性。
4. Constructor 类:代表类的构造方法。
反射的基本操作主要分为以下几个步骤:1. 获取 Class 对象:通过类的全限定名或对象的 getClass() 方法来获取 Class 对象。
2. 获取类的方法、属性、构造方法等信息:通过 Class 对象的方法来获取类的方法、属性、构造方法等信息。
3. 调用类的方法、获取和设置类的属性:通过 Method、Field 类等对象来调用类的方法、获取和设置类的属性等操作。
反射功能的实现为程序的设计和开发提供了更大的灵活性和可扩展性,但需要注意的是,使用反射会影响程序的性能,并且会增加代码的复杂性,因此在使用时需要权衡利弊,谨慎使用。
三、反射获取方法的调用方法反射可以帮助程序在运行时动态地调用类的方法,这为程序的设计和开发提供了更大的灵活性。
在 Java 中,通过反射获取方法的调用方法主要涉及以下几个步骤:1. 获取 Class 对象:通过类的全限定名或对象的 getClass() 方法来获取 Class 对象。
2. 获取方法信息:通过 Class 对象的 getMethod() 方法或getDeclaredMethod() 方法来获取方法的信息。
3. 调用方法:通过 Method 对象的 invoke() 方法来调用方法。
下面将结合具体的代码示例,介绍反射获取方法的调用方法的具体实现。
java反射调用接口中的方法Java反射是一种机制,它允许程序在运行时动态地获取类的信息并操作类的属性和方法。
通过反射,我们可以在运行时调用接口中的方法。
首先,我们需要获取接口的Class对象,可以使用Class.forName()方法或者直接使用接口的class属性。
然后,我们可以使用getDeclaredMethods()方法获取接口中所有的方法,包括私有方法。
接着,我们可以使用getMethod()方法获取指定的方法,然后使用invoke()方法调用该方法。
下面是一个示例代码:```。
public interface MyInterface 。
void sayHello();。
}public class Main 。
public static void main(String[] args) throws Exception 。
Class<?> clazz = Class.forName("MyInterface");。
Method method = clazz.getMethod("sayHello");。
MyInterface obj = new MyInterface() 。
public void sayHello() 。
System.out.println("Hello World!");。
}。
};。
method.invoke(obj);。
}。
}。
```在上面的代码中,我们首先获取了MyInterface接口的Class对象,然后使用getMethod()方法获取sayHello()方法。
接着,我们创建了一个匿名内部类实现了MyInterface接口,并在sayHello()方法中输出了一句话。
最后,我们使用invoke()方法调用了sayHello()方法,输出了“Hello World!”。
需要注意的是,如果接口中的方法是静态方法,我们可以直接使用Class.getMethod()方法获取方法并调用,而不需要创建实例对象。
利⽤java反射机制调⽤类的私有⽅法(推荐)试想⼀下,如果你可以轻易地调⽤⼀个类的私有⽅法,那么是不是说你的封装都失效了?最近在看java的反射机制,发现居然可以利⽤java的反射机制去调⽤其他类的私有⽅法,⾄于这能⼲什么,那就见⼈见智了。
我写的⼀段简易实例代码如下:import ng.reflect.InvocationTargetException;import ng.reflect.Method;/*** @author thomaslwq* @version 创建时间:Sep 4, 2012 9:53:49 PM* 类说明*/public class ReflectionTest {public static void setObjectColor(Object obj) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAcces***ception, InvocationTargetException{ Class cls = obj.getClass();//获得类的私有⽅法Method method = cls.getDeclaredMethod("privateMethod", null);method.setAccessible(true); //没有设置就会报错//调⽤该⽅法method.invoke(obj, null);}public static void main(String args[]) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAcces***ception, InvocationTargetException{setObjectColor(new MyTest());}}//测试类class MyTest{public void setMyTest(){System.out.println("setMyTest");}/**类的私有⽅法**/private void privateMethod(){System.out.println("调⽤了 private Method");}}以上这篇利⽤java反射机制调⽤类的私有⽅法(推荐)就是⼩编分享给⼤家的全部内容了,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。
反射调用private方法
在Java中,我们可以使用反射机制来调用对象的私有方法。
私有方法通常是被定义为对象内部使用的方法,因此无法从外部直接访问。
但是,通过反射机制,我们可以绕过访问限制,并且调用它们。
要使用反射机制调用私有方法,我们需要使用以下步骤:
1. 获取类对象的Class实例:使用Class.forName()方法获取类对象的Class实例。
2. 获取私有方法对象:使用getDeclaredMethod()方法获取私有方法对象。
该方法需要传递两个参数:方法名称和参数类型。
3. 设置私有方法的可访问性:通过setAccessible()方法将私有方法的可访问性设置为true。
4. 调用私有方法:使用invoke()方法调用私有方法。
该方法需要传递两个参数:要调用的对象和方法参数。
需要注意的是,使用反射机制调用私有方法可能会导致程序的不稳定性。
因此,应该尽量避免使用这种方式,除非没有其他可行的解决方法。
- 1 -。
java利⽤反射访问类的私有(private)属性及⽅法java语⾔中,在⼀个类中,为了不让外界访问到有的属性和⽅法,通常将其设置为private,⽤正常的⽅式(对象名.属性名,对象名.⽅法名)将⽆法访问此属性与⽅法,但有没有其他⽅法可以访问呢?答案是有的,这就是java反射带来的便利。
利⽤反射访问类的私有属性及⽅法如下:1.准备⼀个java类,包含私有属性及⽅法:[java] view plain copy print?1. //Exam.java2. public class Exam{3. private String field1="私有属性";4. public String field2="公有属性";5. public void fun1(){6. System.out.println("fun1:这是⼀个public访问权限⽅法");7. }8.9. private void fun2(){10. System.out.println("fun2:这是⼀个private访问权限⽅法");11. }12.13. private void fun3(String arg){14. System.out.println("fun3:这是⼀个private访问权限且带参数的⽅法,参数为:"+arg);15. }16.17. }将其编译成class,然后删除java源⽂件。
注意:删除java源⽂件并⾮必须,但是在实际情况中,我会使⽤的往往不是java源⽂件,⽽是jar包,⽽jar包中的⽂件都是class,所以为了贴近实际的情况,将Exam.java编译成Exam.class⽂件后,删除Exam.java⽂件,只保留Exam.class⽂件。
2.获取类中属性及⽅法的信息第⼀步做好后,接下来进⾏第⼆步:获取类中属性及⽅法的信息。
通过反射,如何操作私有成员变量(取赋值),如何调⽤私有⽅法?Java的反射⼯具很强⼤,有句著名的话:No reflection ,no frameworks.⼯作中直到涉及到UT,才体会到它的重要性,现归纳整理⼀个⼩例⼦:反射⼯具类:1import ng.reflect.Field;2import ng.reflect.InvocationTargetException;3import ng.reflect.Method;45public class ReflectionUtil {67/***8 * 获取私有成员变量的值9 *10*/11public static Object getValue(Object instance, String fieldName)12throws IllegalAccessException, NoSuchFieldException {1314 Field field = instance.getClass().getDeclaredField(fieldName);15 field.setAccessible(true); // 参数值为true,禁⽌访问控制检查1617return field.get(instance);18 }1920/***21 * 设置私有成员变量的值22 *23*/24public static void setValue(Object instance, String fileName, Object value)25throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {2627 Field field = instance.getClass().getDeclaredField(fileName);28 field.setAccessible(true);29 field.set(instance, value);30 }3132/***33 * 访问私有⽅法34 *35*/36public static Object callMethod(Object instance, String methodName, Class[] classes, Object[] objects)37throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,38 InvocationTargetException {3940 Method method = instance.getClass().getDeclaredMethod(methodName, classes);41 method.setAccessible(true);42return method.invoke(instance, objects);43 }44 }1package com.test;23public class Person {45private String name;6private int age;78public Person(String name, int age) { = name;10this.age = age;11 }1213private String getInfo(String str, int num) {14return str + num + " apples";15 }1617 }1import com.test.Person;23public class ReflectTest {45public static void main(String[] args) throws Exception {67 Person person = new Person("jack", 25);89// test get private value10 System.out.println("jack's name:" + ReflectionUtil.getValue(person, "name"));11 System.out.println("jack's age:" + ReflectionUtil.getValue(person, "age"));1213// test set private value14 ReflectionUtil.setValue(person, "name", "jason");15 ReflectionUtil.setValue(person, "age", 10);16 System.out.println("jack's name:" + ReflectionUtil.getValue(person, "name"));17 System.out.println("jack's age:" + ReflectionUtil.getValue(person, "age"));1819// test call private method20 String result = (String) ReflectionUtil.callMethod(person, "getInfo", new Class[] { String.class, int.class }, 21new Object[] { "I hava ", 4 });22 System.out.println("result: " + result);23 }24 }结果:jack's name:jackjack's age:25jack's name:jasonjack's age:10result: I hava 4 apples。
利用java反射调用类的的私有方法
今天和一位朋友谈到父类私有方法的调用问题,本来以为利用反射很轻松就可以实现,因为在反射看来根本不区分是否是pr ivate的,没有想到调用本身的私有方法是可以的,但是调用父类的私有方法则不行,后来纠其原因很有可能是因为getDeclared Method方法和getMethod方法并不会查找父类的私有方法,于是只好自己写递归了,经过尝试果然如此。
把代码放出来方便更多人。
这段代码可以解决很多实际问题,不过利用反射来做的话性能不会太好。
view plaincopy to clipboardprint?
1.package com.syj.util.reflect;
2.
3.import ng.reflect.Method;
4.
5./**
6. * <P>
7. * Title: 私有方法调用工具类
8. * </P>
9. *
10. * <P>
11. * Description:利用java反射调用类的的私有方法
12. * </P>
13. *
14. * <P>
15. * Copyright: Copyright (c) 2007
16. * </P>
17. *
18. * @author 孙钰佳
19. * @main sunyujia@
20. * @date Jun 1, 2008 10:18:58 PM
21. */
22.public class PrivateUtil {
23./**
24. * 利用递归找一个类的指定方法,如果找不到,去父亲里面找直到最上层Object对象为止。
25. *
26. * @param clazz
27. * 目标类
28. * @param methodName
29. * 方法名
30. * @param classes
31. * 方法参数类型数组
32. * @return 方法对象
33. * @throws Exception
34. */
35.public static Method getMethod(Class clazz, String methodName,
36.final Class[] classes) throws Exception {
37. Method method = null;
38.try {
39. method = clazz.getDeclaredMethod(methodName, classes);
40. } catch (NoSuchMethodException e) {
41.try {
42. method = clazz.getMethod(methodName, classes);
43. } catch (NoSuchMethodException ex) {
44.if (clazz.getSuperclass() == null) {
45.return method;
46. } else {
47. method = getMethod(clazz.getSuperclass(), methodName,
48. classes);
49. }
50. }
51. }
52.return method;
53. }
54.
55./**
56. *
57. * @param obj
58. * 调整方法的对象
59. * @param methodName
60. * 方法名
61. * @param classes
62. * 参数类型数组
63. * @param objects
64. * 参数数组
65. * @return 方法的返回值
66. */
67.public static Object invoke(final Object obj, final String methodName,
68.final Class[] classes, final Object[] objects) {
69.try {
70. Method method = getMethod(obj.getClass(), methodName, classes);
71. method.setAccessible(true);// 调用private方法的关键一句话
72.return method.invoke(obj, objects);
73. } catch (Exception e) {
74.throw new RuntimeException(e);
75. }
76. }
77.
78.public static Object invoke(final Object obj, final String methodName,
79.final Class[] classes) {
80.return invoke(obj, methodName, classes, new Object[] {});
81. }
82.
83.public static Object invoke(final Object obj, final String methodName) {
84.return invoke(obj, methodName, new Class[] {}, new Object[] {});
85. }
86.
87./**
88. * 测试反射调用
89. *
90. * @param args
91. */
92.public static void main(String[] args) {
93. PrivateUtil.invoke(new B(), "printlnA", new Class[] { String.class },
94.new Object[] { "test" });
95. PrivateUtil.invoke(new B(), "printlnB");
96. }
97.}
98.
99.class A {
100.private void printlnA(String s) {
101. System.out.println(s);
102. }
103.}
104.
105.class B extends A {
106.private void printlnB() {
107. System.out.println("b");
108. }
109.}
程序的输出结果为
test
b
说明private方法调用成功了不管是自己的私有方法还是父类的私有方法。