您的位置:首页 > 健康 > 美食 > Java反射

Java反射

2024/12/21 23:11:36 来源:https://blog.csdn.net/2302_76680325/article/details/139930566  浏览:    关键词:Java反射

目录

1.回顾

二.反射的概述

2.1Java反射的概念

2.2Java反射的作用

三.Class类

3.1概述

3.2获取类的三种方式

3.2.1 

3.2.2

3.2.3

四.Constructor类

4.1Constuctor方法

4.2具体实例

五.Field类

 六.Method类

 七.反射案例

八.反射的优缺点总结


1.回顾

在了解Java反射之前,我们需要回顾一下之前在java中如何使用类和对象。

1.定义类

public class 类名{String name;.....属性public void 方法名(){} 
}

2.创建已知类的对象,明确知道要创建哪一个类的对象

这一切都是已知的,这对于我们自己写的程序是没有问题的。

但是像框架,tomcat,或者其他的组件(jackson 对象 -->json),事先是不知道具体要处理哪些类的,

只能根据配置文件中配置的类的地址决定要创建并操作哪个类。

那么问题来了,如果我们只知道类的地址,如何使用类?

<servlet-class>com.ffyc.dormserver.web.LoginServlet</servlet-class>
<servlet-class>com.ffyc.dormserver.web.BuildServlet</servlet-class>

框架可以做到给他什么类名,就可以创建给定类的对象,并调用该对象的方法和属性。

1.创建对象

2.将查询到的结果封装到我们创建的对象中(调用setxxx() 调用xxx属性)

那如何实现写一条程序可以处理任何类呢?

答案就是反射机制。

反射机制,可以看做是一种反向使用类。

二.反射的概述

2.1Java反射的概念

Java反射机制是在运行状态,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能被称为Java语言的反射机制。

2.2Java反射的作用

动态获取类的信息

三.Class类

3.1概述

一旦class文件被加载到内存,就会为其创建一个Class对象。任何类被使用时都会创建一个Class对象。

Class类是Java反射机制的基础,通过Class类,可以得到一个类的基本 信息。

  • 一个类在堆中只有一个Class对象,这个Class对象包含了类的完整结构信息
  • 在使用反射的过程中,把方法、属性、构造器都当做对象来处理的
  • Class类对象由系统创建,继承了Object类

3.2获取类的三种方式

3.2.1 

Object类中的getClass方法:适用于1通过对象获得Class实例的情况

 User user = new User();Class class = user.getClass();//通过已知的对象中getClass()方法 获得该对象的Class对象

3.2.2

类名.class方式:适用于通过类名获得Class实例的情况

 User user = new User();Class class = User.class;

3.2.3

Class类的静态方法 forName(String name)

String s = "com.ffyc.javareflect.Demo2.User";
Class class =  Class.forName(s);//把给定地址的类进行加载,为其创建class对象
四.Constructor类
4.1Constuctor方法

public String getName()

返回构造方法名

public T newInstance(Object … initargs)

创建对象【参数为创建对象的数据】

4.2具体实例

getConstructor( )   

获得类中指定的公共构造方法 将获得到的无参构造方法封装到一个 Constructor对象中

getDeclaredConstructor( )

获得类中指定的构造方法(包含私有的)

getConstructors( )

获得所有公共的构造方法

getDeclaredConstructors( )

获得所有的构造方法(包含私有的)

getName( ):返回构造器的全类名
setAccessible( ):爆破,访问私有成员
newInstance( ):创建对象

package com.ffyc.javareflect.Demo2;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;public class Text3 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {String s = "com.ffyc.javareflect.Demo2.User";//加载类,并获得Class对象Class c = Class.forName(s);//通过Class类的对象,来创建User对象//Object userobject = c.newInstance();//System.out.println(userobject);//获取类中的构造方法信息Constructor constructor =  c.getConstructor();//获得类中指定的公共构造方法 将获得到的无参构造方法封装到一个 Constructor对象中Object userobject = constructor.newInstance();//通过构造方法中的newInstance()创建对象System.out.println(userobject);Constructor constructor1 = c.getDeclaredConstructor();//获得类中指定的构造方法(包含私有的)Constructor constructor2 = c.getConstructor(String.class,String.class);//获得公共的有参构造方法Object userobject1 =  constructor2.newInstance("111","222");//创建对象,并为对象数组赋值System.out.println(userobject1);Constructor[] constructors = c.getConstructors();//获得所有公共的构造方法Constructor[] constructors1 = c.getDeclaredConstructors();//获得所有的构造方法(包含私有的)System.out.println(constructors.length);System.out.println(constructors1.length);}
}

 

五.Field类

getField( ) 

获得类中指定公共的属性,把属性封装到一个Field对象中

getDeclaredField( )

获得类中指定的属性(包含私有,受保护,默认,公共),把属性封装到一个Field对象中

getFields( )

获得类中所有的公共属性

getDeclaredFields( )

获得到所有的属性(包含私有的)

getName( ):返回属性名

package com.ffyc.javareflect.Demo2;import java.lang.reflect.Field;public class Text4 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {String s = "com.ffyc.javareflect.Demo2.User";Class c = Class.forName(s);//获得类的Class对象Object userobject = c.newInstance();//创建User类的对象//获得类中的成员变量//获得类中指定公共的属性,把属性封装到一个Field对象中//Field userNameField =  c.getField("userName");//获得类中指定的属性(包含私有,受保护,默认,公共),把属性封装到一个Field对象中Field userNameField =  c.getDeclaredField("userName");//Field[] fields = c.getFields();//System.out.println(fields.length);//获得到所有的属性(包含私有的)Field[] fields =  c.getDeclaredFields();System.out.println(fields.length);//循环所有的属性,为属性赋值for (Field f : fields){f.setAccessible(true);//设置私有属性可以操作f.set(userobject,"111");}System.out.println(userobject);}
}
 六.Method类

getMethod( )

getDeclaredMethod( )

getMethods( )

获得本类和父类所有公共的成员方法

getDeclaredMethods( )

获得本类中所有成员方法

getName( ):返回方法的名称

package com.ffyc.javareflect.Demo2;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;public class Text5 {public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {String s = "com.ffyc.javareflect.Demo2.User";Class c=Class.forName(s);//获得类的Class对象Object userobject=c.newInstance();//创建user类的对象Method eat=c.getMethod("eat");// 执行userobject对象中的 无参的eat方法eat.invoke(userobject);Method eat1=c.getMethod("eat",String.class);eat1.invoke(userobject,"烤肉");Method[] methods=c.getMethods();// 获得本类和父类所有公共的成员方法Method[] methods1=c.getDeclaredMethods();// 获得本类中所有成员方法System.out.println(methods.length);//15System.out.println(methods1.length);//7}
}
 七.反射案例

我们可以自定义java对象转json工具类

下面是代码实例:

package com.ffyc.javareflect.util;import com.ffyc.javareflect.Demo1.Car;
import com.ffyc.javareflect.Demo2.User;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class JasonUtil {/*自定义的对象转json方法 {name:"jim",age:10}*/public String objectToJson(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {String json = "{";Class c = object.getClass();Field[] fields = c.getDeclaredFields();for(Field f :fields){//生成属性的get方法名String get = "get"+(char)(f.getName().charAt(0)-32)+f.getName().substring(1);Method getMethod = c.getMethod(get);//通过get方法名 获得方法json+=f.getName()+":"+getMethod.invoke(object)+",";}json = json.substring(0,json.length()-1);json+="}";return json;}public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {User user = new User();user.setUserName("admin");user.setPassword("111");Car car = new Car();car.setName("大众");car.setColor("黑色");System.out.println(new JasonUtil().objectToJson(user));System.out.println(new JasonUtil().objectToJson(car));}
}
八.反射的优缺点总结
优点:
● 1. 增加程序的灵活性,可以在运行的过程中动态对类进行修改和操作
● 2. 提高代码的复用率,比如动态代理
● 3. 可以在运行时轻松获取任意一个类的方法、属性,并且还能通过反射进行动态
调用
缺点:
● 1. 反射会涉及到动态类型的解析,导致性能要比非反射调用更低
● 2. 使用反射技术通常要在一个没有安全限制的程序运行 .
● 3. 反射可以绕过一些限制访问的属性或者方法,可能会导致破坏代码本身的抽象

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com