JAVA反射机制之Class类API实例介绍 - AJava

合集下载

JavaAPI——反射

JavaAPI——反射

JavaAPI——反射1、类加载器1)类的加载· 当程序要使⽤某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进⾏初始化。

· 加载:就是指将class⽂件读⼊内存,并为之创建⼀个Class对象。

任何类被使⽤时系统都会建⽴⼀个Class对象。

· 连接:· 验证是否有正确的内部结构,并和其他类协调⼀致· 准备负责为类的静态成员分配内存,并设置默认初始化值· 解析将类的⼆进制数据中的符号引⽤替换为直接引⽤· 初始化:就是我们以前讲过的初始化步骤2)类初始化时机 · 创建类的实例 · 访问类的静态变量,或者为静态变量赋值 · 调⽤类的静态⽅法 · 使⽤反射⽅式来强制创建某个类或接⼝对应的ng.Class对象 · 初始化某个类的⼦类 · 直接使⽤java.exe命令来运⾏某个主类 3)类加载器· 负责将.class⽂件加载到内在中,并为之⽣成对应的Class对象。

虽然我们不需要关⼼类加载机制,但是了解这个机制我们就能更好的理解程序的运⾏。

· 类加载器的组成· Bootstrap ClassLoader 根类加载器· Extension ClassLoader 扩展类加载器· Sysetm ClassLoader 系统类加载器4)获取Class⽂件对象的三种⽅式Person类:package cn.itcast_01;public class Person {private String name;int age;public String address;public Person() {}private Person(String name) { = name;}Person(String name, int age) { = name;this.age = age;}public Person(String name, int age, String address) { = name;this.age = age;this.address = address;}public void show() {System.out.println("show");}public void method(String s) {System.out.println("method " + s);}public String getString(String s, int i) {return s + "---" + i;}private void function() {System.out.println("function");}@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";}}测试类:package cn.itcast_01;/** 反射:就是通过class⽂件对象,去使⽤该⽂件中的成员变量,构造⽅法,成员⽅法。

Java采用反射获取class的属性的值

Java采用反射获取class的属性的值

Java采⽤反射获取class的属性的值原理:Java的反射能够获取属性的名称,然后通过invoke调⽤类的某个⽅法。

⽐如有个属性叫userName,这个类写了个⽅法叫getUserName,通过invoke调⽤getUserName这个⽅法。

代码如下import ng.reflect.Field;import ng.reflect.Method;import java.util.HashMap;import java.util.Map;public class ParameterBase{/*** Get Class field and value Map* @return*/public Map<String, String> getClassInfo(){Map<String ,String> fieldsAndValues = new HashMap<String, String>();Field [] fields = this.getClass().getDeclaredFields();for(int i=0; i< fields.length; i++){Field f = fields[i];String value = getFieldValue(this ,f.getName()).toString();fieldsAndValues.put(f.getName(),value);}return fieldsAndValues;}private String getFieldValue(Object owner, String fieldName){return invokeMethod(owner, fieldName,null).toString();}/**** 执⾏某个Field的getField⽅法** @param owner 类* @param fieldName 类的属性名称* @param args 参数,默认为null* @return*/private Object invokeMethod(Object owner, String fieldName, Object[] args){Class<? extends Object> ownerClass = owner.getClass();//fieldName -> FieldNameString methodName = fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1);Method method = null;try{method = ownerClass.getMethod("get" + methodName);}catch (SecurityException e){//e.printStackTrace();}catch (NoSuchMethodException e){// e.printStackTrace();return "";}//invoke getMethodtry{return method.invoke(owner);}catch (Exception e){return "";}}}写⼀个类User继承于ParameterBase并写上⼀个测试代码public class User extends ParameterBase{String userName ;String passWorld;public String getUserName(){return userName;}public void setUserName(String userName){erName = userName;}public String getPassWorld(){return passWorld;}public void setPassWorld(String passWorld){this.passWorld = passWorld;}public static void main(String[] args){User u = new User();u.passWorld = "123";erName = "aaaaa";System.out.println(u.getClassInfo().toString());}}程序输出{passWorld=123, userName=aaaaa}。

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中的反射总结

JAVA中的反射总结

12
try {
13
c = Class.forName("Person");
14
} catch (ClassNotFoundException
15 e) {
16
e.printStackTrace();
17
}
18
Field[] f = c.getDeclaredFields();
19
for (int i = 0; i < f.length; i++) {
e) {
e.printStackTrace();
}
System.out.println("字符串长度:
" + s.length());
}
}
这样就通过无参数的形式构造了一个新的对象,如同正常模式中 通过无参构造方法来构造新对象一样
我们知道,类中除了有无参构造方法,还会存在有参数的构造方法 那在反射中如何通过有参数的形式构造对象呢?接着看
16 args) throws Exception {
17
Person p
18 = new Person("zhangsan",12);
20 String 类
21
//newInstance()方法会抛异常
22
s = (String) c.newInstance();
23
} catch (InstantiationException e)
24 {
25
e.printStackTrace();
} catch (IllegalAccessException
还有一点,无论是有参还是无参,这里所使用的构造方法,原本的类里面必须对应存在 那么,如何才能知道原有类里面的构造方法,普通方法,继承的父类等详细信息呢?接着看

java反射(二)--反射应用案例

java反射(二)--反射应用案例

java反射(⼆)--反射应⽤案例⼀.反射实例化对象 经过⼀系列的分析之后发现虽然可以获取Class类的实例化对象,但是依然觉得这个对象的获取意义不是很⼤,因此可以通过以下⼏个案例去理解反射的核⼼意义--反射实例化对象:获取Class对象之后最⼤的意义并不是在于只是⼀个对象的实例化操作形式,更重要的是Class类中提供有⼀个对象的反射实例化⽅法,在JDK1.9之前的实例化:public T newInstance() throw InstantiationException,IllegalAccessException,该⽅法代替了new 关键字的使⽤,但是在JDK1.9之后则发⽣了变化:class.getDeclaredConstructor().newInstance();--范例:通过newInstance()⽅法实例化对象1package反射.认识反射机制.entity;23/**4 * @author : S K Y5 * @version :0.0.16*/7public class Person {8public Person() { //任何情况下只要实例化对象则⼀定要调⽤类中的构造⽅法9 System.out.println("Person对象实例化了");10 }1112 @Override13public String toString() {14return "我是⼀个好⼈";15 }16 }1public class Demo {2public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {3 Class<?> aClass = Class.forName("反射.认识反射机制.entity.Person");4 Object o = aClass.newInstance(); //实例化对象5 System.out.println(o);6 }7 }--运⾏结果Person对象实例化了我是⼀个好⼈Process finished with exit code 0--现在通过反射实现的对象实例化处理,依然要调⽤类中的⽆参构造⽅法,其本质等价于new 关键字的使⽤,但是该⽅法在JDK1.9之后被替代了,因为默认的Class类中的newInstance()⽅法只能够调⽤⽆参构造,所以很多的开发者认为其描述的不准确,于是将其变换了形式(后续会说明)⼆.反射与⼯⼚设计模式 如果要想进⾏对象的实例化处理除了可以使⽤关键字new 之外,还可以挺过反射机制来完成.那么思考⼀个问题:为什么要提供有⼀个反射的实例化?到底是使⽤关键字new还是使⽤反射进⾏对象实例化呢?--如果想要更好的解决此类问题,最好的解释⽅案就是通过⼯⼚设计模式来解决.⼯⼚设计模式的最⼤特点:客户端的程序类不直接牵扯到对象的实例化管理,只与接⼝发⽣关联,通过⼯⼚了获取接⼝的实例化对象,传统的⼯⼚设计模式:1interface Message{2public void send(); //消息发送3 }4class NetMessage implements Message{ //⽹络消息实现类5 @Override6public void send() {7 System.out.println("发送⽹络消息");8 }9 }10public class FactoryDemo {11public static void main(String[] args) {12 Message message = new NetMessage(); //如果直接实例化则⼀定会有耦合问题13 }14 }--在实际的开发中,接⼝的主要作⽤是为不同的层提供有⼀个操作的标准.但是此时如果直接将⼀个⼦类设置为接⼝实例化操作,那么⼀定会有耦合问题,所以使⽤了⼯⼚设计模式来解决此问题.--范例:传统的⼯⼚设计模式1interface Message {2public void send(); //消息发送3 }45class NetMessage implements Message { //⽹络消息实现类6 @Override7public void send() {8 System.out.println("发送⽹络消息");9 }10 }1112class Factory {13private Factory() {14 } //没有产⽣实例化对象的意义1516public static Message getInstance(String className) {17if ("NetMessage".equals(className)) {18return new NetMessage();19 }20return null;21 }22 }2324public class FactoryDemo {25public static void main(String[] args) {26 Message message = Factory.getInstance("NetMessage");27 message.send();28 }29 }--此种⼯⼚设计模式属于静态⼯⼚设计模式,此时如果追加⼀个⼦类,那么⼯⼚类就需要进⾏相应的修改(追加相应的判断语句),否则⽆法获得新的⼦类的实例化对象.⼯⼚设模式最有效解决的是⼦类与客户端的耦合问题,但是解决的核⼼思想是在于提供有⼀个⼯⼚类作为过渡端,可是随着项⽬的进⾏,Message接⼝可能会有更多的⼦类,⽽且随着时间的推移,⼦类会越来越多,因此⼯⼚类永远都需要修改,并且永⽆停⽌之⽇.--此时最好的解决⽅案就是不使⽤关键字new来完成对象的实例化,因为关键字new在使⽤的时候需要有⼀个明确的类存在.⽽newInstance()的⽅法只需要有⼀个明确表⽰类名称的字符串即可应⽤:1interface Message {2public void send(); //消息发送3 }45class NetMessage implements Message { //⽹络消息实现类6 @Override7public void send() {8 System.out.println("发送⽹络消息");9 }10 }1112class Factory {13private Factory() {14 } //没有产⽣实例化对象的意义1516public static Message getInstance(String className) throws Exception {17return (Message) Class.forName(className).newInstance();18 }19 }2021public class FactoryDemo {22public static void main(String[] args) throws Exception {23 Message message = Factory.getInstance("反射.反射应⽤案例.NetMessage");24 message.send();25 }26 }--此时如果对⼦类继续进⾏扩充的话,是没有必要修改⼯⼚类的.利⽤反射机制实现的⼯⼚设计模式,最⼤的优势在于,对于接⼝的⼦类的扩充,将不再影响到⼯⼚类的定义.但是现在依然需要进⾏思考,在实际的项⽬开发之中,有可能会存在⼤量的接⼝,并且这些接⼝可能都需要通过⼯⼚类来实例化对象,所以此时的⼯⼚设计模式不应该只为⼀个Message接⼝服务,⽽应该变为为所有的接⼝服务(使⽤泛型实现开发需求): 1interface Service {2public void service();45class HouseService implements Service {6 @Override7public void service() {8 System.out.println("为您的住房提供服务.");9 }10 }1112interface Message {13public void send(); //消息发送14 }1516class NetMessage implements Message { //⽹络消息实现类17 @Override18public void send() {19 System.out.println("发送⽹络消息");20 }21 }2223class Factory {24private Factory() {25 } //没有产⽣实例化对象的意义2627/**28 * 获取接⼝实例化对象29 *30 * @param className 接⼝的⼦类31 * @param tClass 描述的是⼀个接⼝的类型32 * @return如果⼦类存在则返回指定接⼝33 * @throws Exception34*/35public static <T> T getInstance(String className, Class<T> tClass) throws Exception {36return tClass.cast(Class.forName(className).newInstance());37 }38 }3940public class FactoryDemo {41public static void main(String[] args) throws Exception {42 Message message = Factory.getInstance("反射.反射应⽤案例.NetMessage",Message.class);43 message.send();44 Service instance = Factory.getInstance("反射.反射应⽤案例.HouseService", Service.class);45 instance.service();46 }47 }--此时的⼯⼚设计模式才是所谓的⾼可⽤的⼯⼚设计模式,⽽这种操作的实现依赖的就是泛型.此时的⼯⼚设计模式将不再受限于指定的接⼝,可以为所有的接⼝提供实例化对象.三.反射与单例设计模式 单例设计模式的核⼼本质在于类内部的构造⽅法私有化,在类的内部产⽣实例化对象之后在外部通过static⽅法获取到实例化对象进⾏类中的结构调⽤.单例设计模式⼀共有两种,懒汉式和饿汉式(饿汉式的单例是不再本次的讨论范围之内的,主要讨论懒汉式的单例)--范例:观察懒汉式单例的问题1class Singleton {2private static Singleton instance = null;34private Singleton() {5 }67public static Singleton getInstance() {8if (instance == null) {9 instance = new Singleton();10 }11return instance;12 }1314public void print() {15 System.out.println("单例模式加载");16 }1718 }20public class LazyLoadDemo {21public static void main(String[] args) {22 Singleton singleton = Singleton.getInstance();23 singleton.print();24 }25 }--此时我们的操作是在单线程的环境下运⾏的,如果使⽤多线程1class Singleton {2private static Singleton instance = null;34private Singleton() {5 System.out.println(Thread.currentThread().getName() + " 实例化单例对象");6 }78public static Singleton getInstance() {9if (instance == null) {10 instance = new Singleton();11 }12return instance;13 }1415public void print() {16 System.out.println("单例模式加载");17 }1819 }2021public class LazyLoadDemo {22public static void main(String[] args) {23for (int i = 0; i < 3; i++) {24new Thread(() -> {25 Singleton.getInstance();26 }, "[单例创建者" + (i + 1) + "]").start();27 }28 }29 }--运⾏结果[单例创建者1] 实例化单例对象[单例创建者2] 实例化单例对象[单例创建者3] 实例化单例对象Process finished with exit code 0--单例设计模式最⼤的特点是在整体运⾏之中,只允许产⽣⼀个实例化对象,当有了若⼲实例化对象之后,那么就不是单例设计模式了,我们可以⼤致分析单例模式的运⾏流程如下: 1.判断instance是否为空? 2.如果instance为空,实例化instance对象 3.返回当前的instance--因此在多线程的设计中,每⼀个线程在执⾏步骤1的时候都会认为此时的对象为空,那么都会去创建这个对象的实例,这样⼀来单例设计模式也就失去了意义,如果想要解决这类问题,关键的核⼼就在于要解决同步处理,⽽解决同步处理的核⼼就是使⽤synchronized关键字1class Singleton {2private static Singleton instance = null;34private Singleton() {5 System.out.println(Thread.currentThread().getName() + " 实例化单例对象");6 }78public static synchronized Singleton getInstance() {9if (instance == null) {10 instance = new Singleton();11 }12return instance;13 }1415public void print() {16 System.out.println("单例模式加载");1819 }2021public class LazyLoadDemo {22public static void main(String[] args) {23for (int i = 0; i < 3; i++) {24new Thread(() -> {25 Singleton.getInstance();26 }, "[单例创建者" + (i + 1) + "]").start();27 }28 }29 }--运⾏结果[单例创建者1] 实例化单例对象Process finished with exit code 0--此时却是进⾏了同步处理,但是这个同步的代价却是很⼤的,因为效率会降低.因为整体代码中实际上只有⼀块区域需要同步处理,那就是instance对象的实例化处理部分,在这样的情况下同步加的未免显得有些草率,更加合理的进⾏同步处理:1class Singleton {2//在对象实例化的时候,应该⽴刻与主内存中的实例对象保持同步,⽽不应该存在副本3private static volatile Singleton instance = null;45private Singleton() {6 System.out.println(Thread.currentThread().getName() + " 实例化单例对象");7 }89public static Singleton getInstance() {10synchronized (Singleton.class) { //static⽅法只能使⽤Singleton.class11if (instance == null) {12 instance = new Singleton();13 }14 }15return instance;16 }1718public void print() {19 System.out.println("单例模式加载");20 }2122 }2324public class LazyLoadDemo {25public static void main(String[] args) {26for (int i = 0; i < 3; i++) {27new Thread(() -> {28 Singleton.getInstance();29 }, "[单例创建者" + (i + 1) + "]").start();30 }31 }32 }。

黑马程序员JavaEE基础--反射之Class类

黑马程序员JavaEE基础--反射之Class类

黑马程序员Java基础--反射之Class类在我们黑马程序员java基础班的课程里,javaEE入门就是首先是创建class类,下面简单介绍一下Java 的Class类、类加载机制!!一、Class类1、class是一个类2、对象照镜子后可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。

3、对于每个类而言,JRE 都为其保留一个不变的Class 类型的对象。

一个Class 对象包含了特定某个类的有关信息。

4、Class 对象只能由系统建立对象5、一个类在JVM 中只会有一个Class实例6、每个类的实例都会记得自己是由哪个Class 实例所生成(1)获取Class 对象的方式[AppleScript] 纯文本查看复制代码?0102030405 /*** @author 传智播客 */Class clazz = null; /**060708091011121314151617 * 1.得到Class对象,有以下三种方式:*///1.1直接通过类名.class的方法得到clazz = Person.class;//1.2通过对象调用getClass()方法获取Object obj = new Person();clazz = obj.getClass();//1.3通过全类名的方式获取,用的较多String className = "com.wang.reflection. clazz = Class.forName(className);(2)Class类的常用方法[AppleScript] 纯文本查看复制代码?010203040506070809101112131415161718 /*** 2.利用类的全类名创建类的对象* Class 类的newInstance()方法*@author 传智播客*/@Testpublic void test2() throws ClassNotFoundException,IllegalAccessException, InstantiationException {String className = "com.wang.reflection.Person";Class clazz = Class.forName(className);//利用Class对象的newInstance()方法来创建类的一个对象//实际调用的是类的无参数的构造器//一般的,一个类声明了一个带参数的构造器,也要声明一个无参数构造器 Object object = clazz.newInstance();System.out.println(object);}二、ClassLoader类装载器是用来把类(class)装载进JVM 的。

java反射机制代码例子

java反射机制代码例子

java反射机制代码例子Java反射机制是Java语言的一个强大特性,它允许程序在运行时动态地获取类的信息,调用对象的方法和构造方法,甚至可以访问和修改对象的属性。

下面是一个简单的Java反射机制代码例子,以展示如何使用Java反射机制获取类的信息并动态地创建对象:```import ng.reflect.Constructor;import ng.reflect.Field;import ng.reflect.Method;public class ReflectionExample {public static void main(String[] args) throws Exception { // 获取Person类的Class对象Class<?> clazz = Class.forName('Person');// 获取Person类的所有构造方法Constructor<?>[] constructors =clazz.getDeclaredConstructors();// 输出Person类的所有构造方法System.out.println('Person类的所有构造方法:');for (Constructor<?> constructor : constructors) {System.out.println(constructor);}// 获取Person类的所有属性Field[] fields = clazz.getDeclaredFields();// 输出Person类的所有属性System.out.println('Person类的所有属性:');for (Field field : fields) {System.out.println(field);}// 获取Person类的所有方法Method[] methods = clazz.getDeclaredMethods();// 输出Person类的所有方法System.out.println('Person类的所有方法:');for (Method method : methods) {System.out.println(method);}// 使用反射机制动态创建Person对象Object person = constructors[1].newInstance('Tom', 20); // 使用反射机制调用Person对象的方法Method method = clazz.getDeclaredMethod('sayHello');method.invoke(person);}}class Person {private String name;private int age;public Person() {}public Person(String name, int age) { = name;this.age = age;}public void sayHello() {System.out.println('Hello, my name is ' + name + ', I'm ' + age + ' years old.');}}```在上述代码中,我们首先使用`Class.forName()`方法获取`Person`类的`Class`对象,然后分别使用`getDeclaredConstructors()`、`getDeclaredFields()`和`getDeclaredMethods()`方法获取`Person`类的构造方法、属性和方法信息。

反射:获取Class类的实例(四种方法)

反射:获取Class类的实例(四种方法)

反射:获取Class类的实例(四种⽅法)Class 类对象照镜⼦后可以得到的信息:某个类的属性、⽅法和构造器、某个类到底实现了哪些接⼝。

对于每个类⽽⾔,JRE 都为其保留⼀个不变的 Class 类型的对象。

⼀个 Class 对象包含了特定某个结构(class/interface/enum/annotation/primitive type/void/[])的有关信息。

Class本⾝也是⼀个类Class 对象只能由系统建⽴对象⼀个加载的类在 JVM 中只会有⼀个Class实例⼀个Class对象对应的是⼀个加载到JVM中的⼀个.class⽂件每个类的实例都会记得⾃⼰是由哪个 Class 实例所⽣成通过Class可以完整地得到⼀个类中的所有被加载的结构Class类是Reflection的根源,针对任何你想动态加载、运⾏的类,唯有先获得相应的Class对象//反射之前,对于Person的操作@Testpublic void test1() {//1.创建Person类的对象Person p1 = new Person("Tom", 12);//2.通过对象,调⽤其内部的属性、⽅法p1.age = 10;System.out.println(p1.toString());p1.show();//在Person类外部,不可以通过Person类的对象调⽤其内部私有结构。

//⽐如:name、showNation()以及私有的构造器}//反射之后,对于Person的操作@Testpublic void test2() throws Exception{Class clazz = Person.class;//1.通过反射,创建Person类的对象Constructor cons = clazz.getConstructor(String.class,int.class);Object obj = cons.newInstance("Tom", 12);Person p = (Person) obj;System.out.println(p.toString());//2.通过反射,调⽤对象指定的属性、⽅法//调⽤属性Field age = clazz.getDeclaredField("age");age.set(p,10);System.out.println(p.toString());//调⽤⽅法Method show = clazz.getDeclaredMethod("show");show.invoke(p);System.out.println("*******************************");//通过反射,可以调⽤Person类的私有结构的。

java反射的常用案例

java反射的常用案例

Java反射的常用案例Java反射是一种强大的工具,允许在运行时检查和修改类、接口、字段和方法。

以下是一些Java反射的常用案例:1.获取类的信息:使用反射,可以获取类的名称、包名、注释等。

Java:Class<?> clazz = String.class;System.out.println("Class Name: " +clazz.getName());System.out.println("Package Name: " +clazz.getPackage().getName());2.获取和修改字段:反射允许您获取类的所有字段,包括私有字段,并修改它们的值。

Java:public class Person {private String name;public String getName() { return name; }public void setName(String name) { = name; }}Person person = new Person();person.setName("John");Class<?> clazz = person.getClass();Field nameField = clazz.getDeclaredField("name");nameField.setAccessible(true); // 设置为可访问,因为它是私有的nameField.set(person, "Doe"); // 修改字段的值System.out.println(person.getName()); // 输出: Doe3.调用方法:使用反射,可以调用任何方法,包括私有方法。

Java:public class Person {public void sayHello() {System.out.println("Hello!");}}Person person = new Person();Class<?> clazz = person.getClass();Method sayHelloMethod =clazz.getDeclaredMethod("sayHello");sayHelloMethod.setAccessible(true); // 设置为可访问,因为它是私有的sayHelloMethod.invoke(person); // 调用方法4.创建对象:使用反射,可以在运行时动态地创建对象。

class类中定义的反射方法

class类中定义的反射方法

class类中定义的反射方法反射(Reflection)是Java中的一个强大而又重要的特性之一,它允许程序在运行时获取一个类的各种信息,并可以在运行时创建对象、调用方法和修改属性等。

Java中的反射机制主要是通过类和基于类的信息来运行。

其中,class类中定义的反射方法是反射的重要组成部分。

下面,我们来逐步了解一下“class类中定义的反射方法”。

步骤一:获取Class对象在Java中,要使用反射,首先需要获取类的Class对象。

有三种方法可以获取Class对象:通过“类名.class”、通过“对象.getClass()”和通过“Class.forName()”。

例如:```javaClass<?> cls1 = String.class; // 通过“类名.class”Class<?> cls2 = "Hello".getClass(); // 通过“对象.getClass()”Class<?> cls3 = Class.forName("ng.String"); // 通过“Class.forName()”```步骤二:获取类的属性信息在获取Class对象之后,可以通过Class中定义的反射方法获取类的属性信息。

Class中定义的与属性相关的反射方法主要有以下几个:1. Field getDeclaredField(String name):获取指定名称的字段(包括私有字段)。

2. Field[] getDeclaredFields():获取本类所有的字段(包括私有字段)。

3. Field getField(String name):获取指定名称的公共字段(即public修饰的字段)。

4. Field[] getFields():获取本类所有的公共字段。

通过这些方法,可以获取类的属性信息并进行相应的操作,例如修改属性值、获取属性值等。

JAVA反射获取class对象三种方式

JAVA反射获取class对象三种方式

JAVA反射(一)获取Class对象的三种方式及其区别1、通过类名.class方式获得,Class<?> cType = ClassName.class; public class Client {public static void main(String[] args) {Class<?> cType1 = Test.class;}}class Test{static {System.out.println("static block");}{System.out.println("dynamic block");}}2、通过Class.forName()方法获得,Class<?> cType = Class.forName("类全名");package com.lynstudy;public class Client {public static void main(String[] args) {try {Class<?> cType2 = Class.forName("com.lynstudy.Test");} catch (ClassNotFoundException e) {e.printStackTrace();}}}class Test{static {System.out.println("static block");}{System.out.println("dynamic block");}}3、通过对象名.getClass()方法获取,Class<?> cType3 = objName.getClass();package com.lynstudy;public class Client {public static void main(String[] args) {Class<?> cType3 = new Test().getClass();}}class Test{static {System.out.println("static block");}{System.out.println("dynamic block");}}总结:三种方式均能够获得Class对象,区别是方法一不执行静态块和动态构造块,方法二执行静态块、不执行动态构造块,方法三需要创建对象,静态块和动态构造块均会执行;注意:静态块仅在类加载时执行一次,若类已加载便不再重复执行;而动态构造块在每次new对象时均会执行。

Java反射API使用实例

Java反射API使用实例

Java反射API使⽤实例/*** 访问Class对应的类所包含的注释:getAnnotation();getDelaredAnnotation();* 访问Class对应的类所包含的内部类:getDeclaredClasses()* 访问Class对应的类所包含的外部类getDeclaringClass()* 访问Class对应的类所继承的⽗类和实现的接⼝等:* getModifiers()返回此类或接⼝的所有修饰符* Class[] getInterfaces() 返回该Class对象对应类所实现的全部接⼝* getPackage();获取此类的包* getName();以字符串形式返回此Class对象所表⽰的类的名称* getSimpleName()以字符串形式返回此Class对象所表⽰类的简称* getSuperclass()返回该Class所表⽰的类的超类对应的Class对象*/ReflectDemo.javapackage com.pb.reflect.classinfo;/**** @author Administrator* 1、包* 2、注解* 3、构造⽅法* 4、⽅法* 5、内部类**/@SuppressWarnings(value="unchecked")@Deprecatedpublic class ReflectDemo {//私有构造⽅法private ReflectDemo(){}//公有的带name参数的构造⽅法public ReflectDemo(String name){}public void info(){}public void info(String str){}class inner{}}TestReflectDemo.javapackage com.pb.reflect.classinfo;import ng.annotation.Annotation;import ng.reflect.Constructor;import ng.reflect.Method;public class TestReflectDemo {public static void main(String[] args) {//下⾯的代码可以获取ReflectDemo的Class对象Class<ReflectDemo> class1 = ReflectDemo.class;//获取ReflectDemo中全部的构造⽅法Constructor[] constructor = class1.getDeclaredConstructors();System.out.println("########ReflectDemo全部的构造⽅法########");for (Constructor constructor2 : constructor) {System.out.println(constructor2.toString());}//获取ReflectDemo的public构造⽅法System.out.println("########ReflectDemo公共的构造⽅法########");Constructor[] constructor1=class1.getConstructors();for (Constructor constructor2 : constructor1) {System.out.println(constructor2.toString());}//获取ReflectDemo的public 的⽅法System.out.println("########ReflectDemo公共的⽅法########");Method[] methods=class1.getDeclaredMethods();for (Method method : methods) {System.out.println(method.toString());}//获取对应类的指定⽅法,⽅法名、⽅法参数的类型,找到info⽅法,info带的参数类型是String try {System.out.println("########ReflectDemo带有String类型参数的info⽅法########");Method method=class1.getMethod("info", String.class);System.out.println(method.toString());} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 获取ReflectDemo的全部注释Annotation[] annotation=class1.getAnnotations();System.out.println("########ReflectDemo所有的注释信息#####");for (Annotation annotation2 : annotation) {System.out.println(annotation.toString());}//获取ReflectDemo的包信息Package package1 = class1.getPackage();System.out.println(package1.toString());// 获取ReflectDemo的内部类Class[] inners = class1.getDeclaredClasses();System.out.println("########ReflectDemo所有的内部类#####");for (Class class2 : inners) {System.out.println(class2.toString());}try {Class inclass = Class.forName("com.pb.reflect.classinfo.ReflectDemo$inner");// 输出内部类的信息System.out.println("########ReflectDemo所有的内部类的信息");System.out.println("inclass对应类的外部类为:"+inclass.getDeclaringClass());System.out.println("inclass对应类的包为:"+inclass.getPackage());System.out.println("inclass对应类的⽗类为:"+inclass.getSuperclass());System.out.println("inclass对应类的名称为:"+inclass.getName());} catch (ClassNotFoundException e) {e.printStackTrace();}}}。

java高新技术

java高新技术

反射的基石---Class类Java的各个类属于同一事物,描述这个同一事物的类名叫做ClassClass有那些属性和方法?ng.Class对于Class类,没有显式的构造方法,所以不能直接new Class()来获取Class的实例,在类加载器中Class调用默认方法时由JVM来自动构造Class类Class对象实例表示某个类的字节码,所以可以通过如下方式构造:Class cls1 = 类名.class 如Person.classClass cls2 = 类的实例对象.getClass() 如p.getClass()Class cls3 = Class.forName("ng.String") --- 在反射中通常用这种方法八个基本数据类型分别对应八个Class对象,void也有对应的Class对象:void.class/Void.TYPEClass的isPrimitive方法可以检测一个类是不是基本类型注意:数组也是一种类型但不是基本类型isArray方法判定类型总结:只要在源程序中出现的类型,都会有一个Class实例对象例如int[] void等反射的概念反射就是把java类中的各种成分映射成为相应的java类如Field、Method、Constructor等构造方法的反射获取一个类的所有构造方法Constructor[ ] constructors = Class.forName("ng.String").getConstructors()获取一个类的某个构造方法Constructor constructor = Class.forName("ng.String").getConstructors(StringBuffer.class) 创建对象实例无参数的构造实例String string = constructor.newInstance()有参数的构造实例String string = constructor.newInstance(args)成员变量的反射Point p = new Point()可见成员变量Field fieldY = p.getClass().getField("y")获取成员变量的值fieldY.get(p)---fieldY不是对象身上的值而是类的值,要获取某个对象的具体值,需要指定具体的对象不可见成员变量Field fieldX = p.getClass().getDeclaredField("x")获取成员变量的值fieldX.setAccessible(true)fieldX.get(p)成员变量反射的综合实例---动态改变成员变量的值Field[ ] fileds = p.getClass().getFields()for(Field field:fields){if(field.getType() == String.class){String oldValue = (String)filed.get(p)String newValue = oldValue.replace(oldChar, newChar)field.set(p, newValue)}}注意:字节码的比较用==,因为同一个类在JVM中只有一份字节码成员方法的反射获取一个类中的某一个方法Method method = string.getClass().getMethod("charAt", int.class)调用该方法method.invoke(string, 1) ---jdk1.5method.invoke(string, new Object[ ]{2}) ---jdk1.4注意:如果invoke的第一个参数是null,则表明该方法是静态方法JDK1.4和JDK1.5在invoke方法中的区别:jdk1.4:invoke(object, object[ ] objects)jdk1.5:invoke(object, object... objects)对接收数组参数的成员方法进行反射---main方法的调用String startingClassName = args[0]Method mainMethod =Class.forName(startingClassName).getMethod("main",String[].class) mainMethod.invoke(null, new Object[ ]{new String[]{str1,str2,str3}})或mainMethod.invoke(null, (Object)new String[]{str1,str2,str3})数组的反射数组与Object的关系及其反射类型具有相同的元素类型和相同维度的数组属于同一个Class数组类型的父类也是Object基本类型不是ObjectArrays类中包含大量对数组进行操作的方法Arrays.asList(Object[] obj) ---所以对于整型数组不能将结果正确显示出来可以获取数组中某一个元素的类型但是不能够获取整个数组的类型数组的反射应用void printObject(Object obj){Class clazz = obj.getClass();if(clazz.isArray()){int length = Array.getLength(obj);for(int i=0;i<length;i++){System.out.println(Array.get(obj, i));}}else{System.out.println(obj)}}反射的综合案例hashCode 哈希算法的集合中hashCode值才有价值比如Set和Map集合hashCode是对内存地址位置的一个映射每个对象创建时都会分配一个hashCode 字节码相同的对象所分配的hashCode相同不是哈希集合不会分配hashCode 比较两个对象是否相同的时候先判定两个对象的hashCode是否相等内存泄漏:如果将一个对象添加到哈希集合中以后再对该对象的属性进行修改(该属性和hashCode关联)当移除该对象时原本的对象还存在因为修改属性后会为该对象生产一个新的hashCode,移除的是新的hashCode对应的对象这就造成了内存泄漏反射的作用---实现框架功能·框架及框架要解决的核心问题我要做房子卖给用户住由用户自己安装门窗,我做的房子就是框架,用户需要使用我的框架,把门窗安装进我提供的框架中,框架和工具类有区别,工具类被用户的类调用,而框架调用用户提供的类我在写框架时,用户可能还没有用到框架,那么框架如何调用以后写的类?在写框架时无法知道要被调用的类名,所以无法直接new某个类的实例对象,而要用到反射方式来做资源文件的定位?·类加载器配置文件往往是通过类加载器来加载的//这种方式可读可写InputStream ips = new FileInputStream("config.properties");OutputStream ops = new FileOutputStream("config.properties");内省Introspector用于处理JavaBean---特殊的Java类JDK中提供了对JavaBean进行操作的一些API 这套API就称为内省值对象(Value Object :VO)对JavaBean的简单内省操作PropertyDescriptor类及其getReadMethod和getWriteMethod方法对JavaBean的复杂内省操作Introspector.getBeanInfo方法返回一个封装了当前JavaBean信息的类使用BeanUtils工具包操作JavaBeanBeanUtils.getProperty(obj, property)BeanUtils.setProperty(obj, property,value)---value是字符串形式对于JavaBean当中的Date类型属性还可以这样操作---属性链BeanUtils.getProperty(obj, "birthday.time")BeanUtils还有许多其他方法参见API除了对JavaBean进行操作BeanUtils还可以对Map进行操作BeanUtils.setProperty(map, key, value)PropertyUtilsBeanUtils是以字符串形式对JavaBean进行操作,数据类型转换由BeanUtils内部完成PropertyUtils是以属性本身类型对JavaBean进行操作注解Annotation元注解(注解的注解叫元注解)为@Retention(RetentionPolicy.RUNTIME)的注解才能通过反射动态获取RetentionPolicy.SOURCE,RetentionPolicy.CLASS,RetentionPolicy.RUNTIME分别对应:java源文件---->class文件---->内存中的字节码,注解默认保存在class文件中,@Retention 注解反映的是修饰类或接口的生命周期@Override、@SuppressWarning和@Deprecated都是对应RetentionPolicy.SOURCE,因为他们在编译器编译完成之后就没有意义了注意:Type是一个接口而Class是一个实现了Type接口的类@Target注解反映可以表现在哪些变量上面:ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.LOCAL_V ARIABLE,ElementType.METHOD, ElementType.PACKAGE,ElementType.PARAMETRE,ElementType.TYPE注解的属性:注解相当于一个类的话那么注解的属性就相当于类中的方法public @interface ItcastAnnotation{String color() default "blue";String value() default "hello";int[] array();EnumLamp lamp(); //枚举MetaAnnotation annotationAttr(); //注解}调用的时候:@ItcastAnnotation(color='red',value='hello')如果ItcastAnnotation只有value属性的话可以直接写作:@ItcastAnnotation("hello")数组的属性junit框架--单元测试:junit4采用注解的方式实现单元测试,注意Before/After和BeforeClass/AfterClass 的区别泛型Generics参数化类型和原始类型的兼容性:Collection<String> c = new Vector(); //warningCollection c = new Vector<String>(); //warning参数化类型不考虑继承关系Collection<String> c = new Vector<Object>(); //errorCollection<Object> c = new Vector<String>(); //error在创建数组实例的时候,不可以使用参数化类型Vector<Integer> vectorList[] = new Vector<Integer>[10];Vector typeof Integer?通配符:Class<?> ?表示任意类型:Class<Integer> <=> Class<?> 但是需要注意的是Class<?>类型不可以调用包含类型参数的方法可以调用不包含类型参数的方法如:Collection.add(1)会报错而Collection.size()是正确的即?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数无关的方法,不能调用与参数有关的方法?通配符的扩展:Vector<? extends Number> x = new Vector<Integer>() ---?表示Number或Number的子类Vector<? super Integer> x = new Vector<Number>() ---?表示Integer或Integer的父类泛型的综合应用:HashMap并没有实现Iterable接口所以需要通过HashSet<Map.Entry<K, V>>来实现iterator的迭代遍历HashMap<String, Integer> hm = new HashMap<String, Integer>();Set<Map.Entry<String, Integer>> mes = hm.entrySet();在JSP页面当中对Set或Map集合进行迭代:<c:forEach items="${map}" var="entry">${entry.key}:${entry.value}</c:forEach>自定义泛型方法由C++得模板函数引入自定义泛型:template<class T>T add(T x, T y){Return (T)(x+y);}Java语言中的泛型功能不如模板函数强大(受JVM的限制),仅限于表面Private <T> T add(T x, T y){return (T)(x + y);} --- java会对T进行类型推断所谓的推断就是指x和y类型的交集只有引用类型才能作为泛型方法的实际参数除了在应用泛型的时候使用extends限定符之外,在定义泛型的时候也可以使用extends限定符,并且用&界定多个边界private <A extends Annotation> A getAnnotation(...){}普通方法、静态方法和构造方法都可以使用泛型,也可以使用类型变量表示异常private static <T extends Exception> sayHello() throws T{try{...}catch(T t){throw (T)t;}}自定义泛型类如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型参数要保持同一个实际类型时,这时候要采用泛型参数的方式进行定义,也就是类级别的泛型public class GenericDao<T>{private T field;public void save(T t){}public T findById(int id)}注意:当一个实例变量被声明为泛型时,只能被实例变量和方法调用,而不能被静态变量和静态方法调用,因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数通过反射获取泛型的实际参数类型Method method = Test.class.getMethod("applyVector", Vector.class);Type[] types = method.getGenericParameterTypes();ParameterizedType pType = (ParameterizedType)types[0];System.out.println(pType.getRawType());System.out.println(pType.getActualTypeArguments()[0]);类加载器ClassLoader树状结构类加载器的委托机制当java虚拟机要加载一个类时到底指派哪个类加载器去加载呢?首先当前线程的类加载器去加载线程中的第一个类;如果类A中引用了类B,java虚拟机将使用加载类A的类加载器来加载类B;还可以直接调用ClassLoader.loadClass()方法来指定某个类加载器去加载某个类。

Java反射-获取.class中的所有方法

Java反射-获取.class中的所有方法

//打印方法的参数类型(不带包名)
//System.out.println(temp.getName());
//打印方法的参数类型(带包名)
}

System.out.println();
}
} }
class Person {
//方法s1
public static void s1(String str_name,int age) {
登录后才能查看或发表评论立即登录或者逛逛博客园首页
Java反射 -获取 .class中的所有方法
import ng.reflect.Method; import ng.reflect.Modifier;
public class Main { public static void main(String[] args) { Class clazz = null; try { clazz = Class.forName("Person"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
}
//方法s2
public static Person s2() { return null;
} }
emmm 好好研究···
Method[] m = clazz.getDeclaredMethods(); for(Method t : m) {
System.out.println(Modifier.toString(t.getModifiers()));
//获取方法的修饰符
System.out.println(t.getReturnType().getName()); //带包名的 // System.out.println(t.getReturnType().getSimpleName()); //带包名的

java 反射调用示例

java 反射调用示例

java 反射调用示例一、反射的基本概念Java反射是指在运行时,动态地获取和操作类的信息的机制。

通过反射机制,我们可以在运行时获取类的方法、属性、构造函数等信息,并进行相应的操作。

反射机制是Java语言的一种特性,它使得我们可以在运行时动态地加载和使用类,而不需要在编译时确定类的类型。

二、反射的使用方法Java反射提供了一系列的类和方法,用于获取和操作类的信息。

下面以一个简单的示例来介绍反射的使用方法。

1. 获取类的Class对象在Java中,每个类都有一个对应的Class对象,可以通过该对象获取类的信息。

获取Class对象的方式有三种:1) 通过类名获取:使用Class.forName()方法,传入类的全限定名,返回对应的Class对象;2) 通过对象获取:使用对象的getClass()方法,返回对象所属类的Class对象;3) 通过类字面常量获取:使用类字面常量,例如String.class,返回对应的Class对象。

2. 获取类的方法信息通过Class对象,我们可以获取类的方法信息,包括方法名、参数类型、返回值类型等。

通过Class对象的getMethods()方法,可以获取类的所有公共方法,返回一个Method数组。

通过Method 对象,我们可以获取方法的详细信息,例如方法名、参数类型、返回值类型等。

3. 调用方法通过反射,我们可以在运行时动态地调用类的方法。

通过Method 对象的invoke()方法,可以调用方法并传入相应的参数。

如果调用的方法是静态方法,则可以将对象设置为null;如果调用的方法是实例方法,则需要传入对象作为调用方法的目标。

4. 获取类的属性信息通过Class对象,我们可以获取类的属性信息,包括属性名、类型等。

通过Class对象的getFields()方法,可以获取类的所有公共属性,返回一个Field数组。

通过Field对象,我们可以获取属性的详细信息,例如属性名、类型等。

java学习笔记之反射—Class类实例化和对象的反射实例化

java学习笔记之反射—Class类实例化和对象的反射实例化

java学习笔记之反射—Class类实例化和对象的反射实例化反射之中所有的核⼼操作都是通过Class类对象展开的,可以说Class类是反射操作的根源所在,但是这个类的实例化对象,可以采⽤三种⽅式完成。

ng.Class类的定义:public final class Class<T>extends Objectimplements Serializable, GenericDeclaration, Type, AnnotatedElement, TypeDescriptor.OfField<Class<?>>, Constable1.Object类⽀持:Object类可以根据实例化对象获取Class对象:public final Class<?> getClass()这种⽅式有⼀个缺点:如果现在只是想获得Class类对象,则必须产⽣指定类对象后才可以获得,会造成⼀个⽆⽤的对象产⽣代码:Person per = new Person();//已经存在有指定类的实例化对象Class<? extends Person> cls = per.getClass();2.JVM直接⽀持:采⽤“类.class”的形式实例化代码:Class<? extends Person> cls2 = Person.class;3.Class类⽀持:在Class类⾥⾯提供有⼀个static⽅法:加载类:public static Class<?> forName(String className) throws ClassNotFoundException这种模式最⼤的特点是可以直接采⽤字符串的形式定义要使⽤的类型,并且程序不需要编写任何的import程序注意:使⽤该⽅法时参数必须是完整类名,如以下代码中IOtest为包名,InputUtil是类名Class<?> cls3 = Class.forName("IOtest.InputUtil");完整代码:package Reflect;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {// TODO Auto-generated method stub// 1、Object类⽀持Person per = new Person();//已经存在有指定类的实例化对象Class<? extends Person> cls = per.getClass();System.out.println(per);System.out.println(cls.getName());//获取的是类的完整名称// 2、JVM直接⽀持Class<? extends Person> cls2 = Person.class;System.out.println(cls2.getName());// 3、Class类⽀持Class<?> cls3 = Class.forName("IOtest.InputUtil");//不需要⽤import导⼊IOtest包System.out.println(cls3.getName());}}class Person{}获取Class对象之后最⼤的意义实际上并不是在于这是⼀个对象,更重要的是Class类⾥⾯提供有⼀个对象的反射实例化⽅法(代替了关键字new):在jdk1.9以前的实例化:public T newInstance() throws InstantiationException,IllegalAccessExceptionjdk1.9之后:clazz.getDeclaredConstructor().newInstance()通过反射实现的对象实例化处理,依然要调⽤类中的⽆参构造⽅法,其本质等价于“类对象 = new 类()”,也就是说相当于隐藏了关键字new,⽽直接使⽤字符串进⾏了替代代码实例:/** 通过newInstance()⽅法实例化Student类对象*/package Reflect;public class ReflectDemo2 {public static void main(String[] args) throws Exception {// TODO Auto-generated method stubClass<?> cls = Class.forName("mldn.Student");Object obj = cls.newInstance();//实例化对象,jdk1.9后被废除System.out.println(obj);//jdk1.9之后:被clazz.getDeclaredConstructor().newInstance()替代Object o = cls.getDeclaredConstructor().newInstance();System.out.println(o);}}。

Java反射机制常用API

Java反射机制常用API

Java反射机制常用APIJava反射机制常用APIClass是Reflection故事起源。

针对任何您想探勘的class,唯有先为它产生一个Class object,接下来才能经由它唤起为数十多个的Reflection APIs。

首先看看Class,反射的核心类,所有的操作都是围绕该类来生成的。

Java允许我们从多种管道为一个class生成对应的Class object:Java代码//运用Class.forName()Class c1 = Class.forName("ng.String");//运用getClass(),每个object都有此方法String str = "abc";Class c2 = str.getClass();//运用getSuperclass(),每个class对象都有此方法Button b = new Button();Class c3 = b.getClass();Class c4 = c3.getSuperclass();//运用.class 语法Class c5 = String.class;Class c6 = Integer.class;//ng.IntegerClass c7 = java.awt.Button.class;Class c8 = int.class;//Integer.TYPE==int.classClass c9 = int[].class;//运用primitive wrapper classes(原始包装类)的TYPE语法Class c10 = Integer.TYPE;//表示基本类型int的Class实例,与int.class返回结果一样Class c11 = Byte.TYPE;Class c12 = Character.TYPE;Class c13 = Short.TYPE;Class c14 = Boolean.TYPE;Class c15 = Long.TYPE;Class c16 = Float.TYPE;Class c17 = Double.TYPE;Class c18 = Void.TYPE;Java的访问控制public, protected, private这些限定符和C++一样。

Java中反射API的使用

Java中反射API的使用

Java中反射API的使⽤⼀、什么是反射: 在运⾏状态中,对于任意⼀个类,都能够获取到这个类的所有属性和⽅法(包括私有的⽅法和属性),对于任意⼀个对象,都能够调⽤它的任意⼀个⽅法和属性(包括私有的⽅法和属性),这种动态获取的信息以及动态调⽤对象的功能就称为java语⾔的反射机制。

通俗点讲,通过反射可以获取该类所有的属性和⽅法。

⼆、API 使⽤:public static void test() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { // 1、获取字节码⽂件的三种⽅法Class psnClass = Class.forName("model.Person"); //通过Class类中的静态⽅法forName,直接获取到⼀个类的字节码⽂件对象,此时该类还是源⽂件阶段,并没有变为字节码⽂件。

Class psnClass2 = Person.class; // 当类被加载成.class⽂件时,此时Person类变成了.class,在获取该字节码⽂件对象,也就是获取⾃⼰,该类处于字节码阶段。

Person s = new Person();Class psnClass3 = s.getClass(); // 通过类的实例获取该类的字节码⽂件对象,该类处于创建对象阶段 //通过字节码对象调⽤⽆参构造器创建Person实例对象Person person = (Person) psnClass.newInstance();person.getNameAndAge();//通过字节码对象获取有参构造器对象,创建Person实例对象Constructor constructor = psnClass.getConstructor(int.class, String.class);Person person1= (Person) constructor.newInstance(18,"wu");person1.getNameAndAge();Constructor[] constructors = psnClass.getConstructors();for (Constructor c : constructors) {System.out.println("构造器:" + c.getName());}// 获得指定⽅法Method getName = psnClass.getDeclaredMethod("getName");getName.setAccessible(true); // 设置可访问getName.invoke(person); // 执⾏⽅法Method[] declaredMethods = psnClass.getDeclaredMethods();for (Method m : declaredMethods) {System.out.println("⽅法名: " + m.getName());m.setAccessible(true);m.invoke(person1);}// 获得私有属性Field name = psnClass.getDeclaredField("name");name.setAccessible(true);name.set(person,"li");Method getNameLi = psnClass.getDeclaredMethod("getName");getName.setAccessible(true);getName.invoke(person);Field[] fields = psnClass.getDeclaredFields();for (Field f : fields) {System.out.println("成员变量: " + f.getName());}}。

Java反射获取class对象的三种方式,反射创建对象的两种方式

Java反射获取class对象的三种方式,反射创建对象的两种方式

Java反射获取class对象的三种⽅式,反射创建对象的两种⽅式Java反射获取class对象的三种⽅式,反射创建对象的两种⽅式1、获取Class对象在 Java API 中,提供了获取 Class 类对象的三种⽅法:第⼀种,使⽤ Class.forName 静态⽅法。

前提:已明确类的全路径名。

第⼆种,使⽤ .class ⽅法。

说明:仅适合在编译前就已经明确要操作的 Class第三种,使⽤类对象的 getClass() ⽅法。

适合有对象⽰例的情况下package com.reflection;/*** Created by Liuxd on 2018-08-15.*/public class User {private String name;private Integer age;public User() {}public User(String name, Integer age) { = name;this.age = age;}public String getName() {return name;}public void setName(String name) { = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}}User类package com.reflection;/*** Created by Liuxd on 2018-08-15.*/public class TestReflection {public static void main(String[] args) {// 第⼀、通过Class.forName⽅式Class clazz1 = null;try {clazz1 = Class.forName("er");} catch (ClassNotFoundException e) {e.printStackTrace();}// 第⼆、通过对象实例⽅法获取对象Class clazz2 = User.class;// 第三、通过Object类的getClass⽅法User user = new User();Class clazz3 = user.getClass();System.out.println(clazz1);System.out.println(clazz2);System.out.println(clazz3);}}2、获取对象实例共两种⽅法:⼀、直接⽤字节码⽂件获取对应实例// 调⽤⽆参构造器,若是没有,则会报异常Object o = clazz.newInstance();⼆、有带参数的构造函数的类,先获取到其构造对象,再通过该构造⽅法类获取实例://获取构造函数类的对象Constroctor constroctor = clazz.getConstructor(String.class,Integer.class);// 使⽤构造器对象的newInstance⽅法初始化对象Object obj = constroctor.newInstance("龙哥", 29);package com.reflection;import ng.reflect.Constructor;/*** Created by Liuxd on 2018-08-15.*/public class TestReflection {public static void main(String[] args) {// 第⼀、通过Class.forName⽅式Class clazz1 = null;try {clazz1 = Class.forName("er");} catch (ClassNotFoundException e) {e.printStackTrace();}// 第⼆、通过对象实例⽅法获取对象Class clazz2 = User.class;// 第三、通过Object类的getClass⽅法User user = new User();Class clazz3 = user.getClass();System.out.println(clazz1);System.out.println(clazz2);System.out.println(clazz3);User user1 = null;try {user1 =(User) clazz1.newInstance();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}user1.setName("终结者");user1.setAge(1500);System.out.println("user1:"+user1.toString());User user2 = null;try {// 获取构造函数Constructor constroctor = clazz2.getConstructor(String.class,Integer.class);// 通过构造器对象的newInstance⽅法进⾏对象的初始化user2 = (User) constroctor.newInstance("龙哥",29);} catch (Exception e) {e.printStackTrace();}System.out.println("user2:"+user2.toString());}}---------------------转载来⾃:作者:刘雪东来源:CSDN原⽂:https:///jiahao1186/article/details/81699582。

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

JAVA反射机制之Class类API实例介绍- AJavaJAVA反射机制之Class类API实例介绍核心提示:本文针对jdk6.0中ng.Class类的API进行了简单的实例应用,例子简单易懂,比较适合入门级阅读。

实例简介:/* *IncludeInnerClass类中包含了三种访问控制的内部类,并且以这三个内部类的引用对象和一个整型数作为属性,在外部类的方法中分别调用了内部本文针对jdk6.0中ng.Class类的API进行了简单的实例应用,例子简单易懂,比较适合入门级阅读。

实例简介:/**IncludeInnerClass类中包含了三种访问控制的内部类,并且以这三个内部类的引用对象和一个整型数作为属性,在外部类的方法中分别调用了内部类的方法*外部类有两个构造方法,一个默认构造方法,一个带一个整型参数的构造方法*Class类的API大家可以直接查阅jdk手册*getMethods()系列方法基本与getConstructors()系列方法类似,仅在后序文章中对getMethods()系列方法的一个特例做深入介绍,将涉及covariant return type 和bridge methods。

*/package classTest;import ng.reflect.Field;import ng.reflect.Modifier;import ng.reflect.Constructor;import ng.reflect.Method;class IncludeInnerClass implements Runnable{class DefaultInnerClass{int i;public DefaultInnerClass(){}DefaultInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am DefaultInnerClass.");}}private class PrivateInnerClass{int i;PrivateInnerClass(){}PrivateInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am PrivateInnerClass.");}}public class PublicInnerClass{int i;public PublicInnerClass(){}PublicInnerClass(int i){this.i = i;}void innerMethod(){System.out.println("I am PublicInnerClass.");}}DefaultInnerClass deic;private PrivateInnerClass pric;public PublicInnerClass puic;int i;public IncludeInnerClass(){deic = new DefaultInnerClass(1);pric = new PrivateInnerClass(2);puic = new PublicInnerClass(3);this.i=10;}private IncludeInnerClass(int i){deic = new DefaultInnerClass(1);pric = new PrivateInnerClass(2);puic = new PublicInnerClass(3);this.i=i;}public void method(){deic.innerMethod();pric.innerMethod();puic.innerMethod();}public void run(){method();}}public class GetInnerClassTest {public static void main(String[] args) throws SecurityException{//直接生成外部类的对象,并调用外部类的方法IncludeInnerClass iic = new IncludeInnerClass();System.out.println("regular use of outer class object.");iic.method();System.out.println("+++++++++++++++++++++++++++++ ++++++");//如何生成内部类对象:必须通过外部类实例IncludeInnerClass.DefaultInnerClass iicdic = iic.new DefaultInnerClass(2);System.out.println("regular use of inner class object.");System.out.println(iicdic.i);iicdic.innerMethod();System.out.println("+++++++++++++++++++++++++++++ ++++++");//动态加载外部类并通过getDeclaredClasses()得到其包含的内部类名称Class&lt;?&gt; clc = iic.getClass();Class&lt;?&gt;[] classArray =clc.getDeclaredClasses();System.out.println("print inner class name.");for(int i=0;i&lt;classArray.length;i++){System.out.println(classArray[i].getName());}System.out.println("+++++++++++++++++++++++++++++++++++");//动态加载内部类,调用getDeclaringClass()得到其外部类Class&lt;?&gt; clac = iicdic.getClass();Class&lt;?&gt; outClass =clac.getDeclaringClass();System.out.println("print outer class name.");System.out.println(outClass.getName());//如果没有外部类则返回null,小心空指针异常System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到所在的包Package pack;pack = clc.getPackage();System.out.println("print package name.");System.out.println(pack.getName());System.out.println(pack.equals(clac.getPackage()));//内部类和外部类的包名相同System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类继承的接口Class&lt;?&gt;[] interfaceArray =clc.getInterfaces();System.out.println("print interface name.");for(int i=0;i&lt;interfaceArray.length;i++){System.out.println(interfaceArray[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的属性Field[] field = clc.getDeclaredFields();System.out.println("print outer class fields");for(int i=0;i&lt;field.length;i++){System.out.println(Modifier.toString(field[i].getModifiers())+" "+field[i].getType().getName()+" "+field[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的指定属性Field f = null;try {f = clc.getDeclaredField("pric");} catch (NoSuchFieldException e) {System.out.println("no such Field.");}System.out.println("print the field we want.");System.out.println(Modifier.toString(f.getModifiers())+" "+f.getType().getName()+" "+f.getName());System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类的所有构造函数及其修饰符和参数:getDeclaredConstructors()得到所有的构造函数Constructor&lt;?&gt;[] allConArray =clc.getDeclaredConstructors();System.out.println("print all constructor of outer class.");for(int i=0;i&lt;allConArray.length;i++){System.out.println("-----------------------------------");System.out.println("print modifier and name");System.out.println(Modifier.toString(allConArray[i].getModi fiers())+" "+allConArray[i].getName());System.out.println("print parameter type");Class&lt;?&gt;[] caparam =allConArray[i].getParameterTypes();for(int j=0;j&lt;caparam.length;j++){System.out.println(caparam[j].getName());}}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到外部类所有public的构造函数:getConstructor()Constructor&lt;?&gt;[] publicCon =clc.getConstructors();System.out.println("print all public constructor of outer class.");for(int i=0;i&lt;publicCon.length;i++){System.out.println(Modifier.toString(publicCon[i].getModifi ers())+" "+publicCon[i].getName());}System.out.println("+++++++++++++++++++++++++++++ ++++++");//得到指定的外部类构造函数getDeclaredConstructor(Class&lt;?&gt;[]),形参为指定构造函数的参数类型数组Class&lt;?&gt;[] parameterTypes = new Class[1];parameterTypes[0] = int.class;Constructor&lt;?&gt; con = null;try {con =clc.getDeclaredConstructor(parameterTypes);} catch (NoSuchMethodException e) {System.out.println("NO SUCH CONSTURCTOR!!!");}System.out.println("we want the constructor with one parameter.");System.out.println(Modifier.toString(con.getModifiers())+" "+con.getName());System.out.println(con.getParameterTypes()[0].getName() );System.out.println("+++++++++++++++++++++++++++++ ++++++");//Method类与Constructor基本一致,这里不做介绍。

相关文档
最新文档