1. java反射的作用。
1. Java反射包reflection提供对Class,Method,field,constructor1 等信息的封装类型。
2. 通过这些api可以轻易获得一个类的各种信息并且可以进行实例化,方法调用等。
类中的private参数可以通过setaccessible方法强制获取。
3. 反射的作用可谓是博大精深,JDK动态代理生成代理类的字节码后,首先把这个类通过defineclass定义成一个类,然后用class.for(name)会把该类加载到jvm,之后我们就可以通过,A.class.GetMethod()获取其方法,然后通过invoke调用其方法,在调用这个方法时,实际上会通过被代理类的引用再去调用原方法。
2. JAVA中反射是什么
JAVA中反射是动态获取信息以及动态调用对象方法的一种反射机制。
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态语言的一个关键性质。
Java反射的功能是在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,在运行时判断任意一个类所具有的成员变量和方法,在运行时调用任意一个对象的方法,生成动态代理。
(2)java反射代理扩展阅读:
JAVA中反射实例:
1、Class superClass=clazz.getSuperclass();//获取父类。
System.out.println("getSuperclass:"+superClass)。
2、Class[] interfaces=clazz.getInterfaces();//获取实现接口。
System.out.println("getInterfaces:"+interfaces.length)。
3、Constructor[] cons=clazz.getConstructors();//构造方法。
System.out.println("getConstructors:"+cons.length)。
参考资料来源:网络: JAVA反射机制
3. java中什么是反射,反射怎么用,什么场景用有没有替代方案
1、反射简言之就是在编译时无法拿到某一个类,但是可以在运行时动态获取这个类,这样去使用某一个类,就是反射的使用场景。
2、代替反射或者类似的操作,可以通过DI实现IOC .依赖注入,动态代理。
4. java中的反射可以做什么
Java反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;生成动态代理。
JAVA有着一个非常突出的动态相关机制:Reflection。
这个字的意思是“反射、映象、倒影”,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语。
5. java课程分享Java的反射机制
Java反射机制是一个非常强大的功能,在很多大型项目比如Spring,Mybatis都可以看见反射的身影。通过反射机制我们可以在运行期间获取对象的类型信息,利用这一特性我们可以实现工厂模式和代理模式等设计模式,同时也可以解决Java泛型擦除等令人苦恼的问题。下面java课程http://www.kmbdqn.com/就从实际应用的角度出发,来应用一下Java的反射机制。
反射基础
p.s:本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的QuickStart。
在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的反射类Class,在Java中我们有三种方法可以获取一个对象的反射类。
通过getClass方法
在Java中,每一个Object都有一个getClass方法,通过getClass方法我们可以获取到这个对象对应的反射类:
Strings="ziwenxie";
Class<?>c=s.getClass();
通过forName方法
我们也可以调用Class类的静态方法forName:
Class<?>c=Class.forName("java.lang.String");
使用.class
或者我们也可以直接使用.class:
Class<?>c=String.class;
获取类型信息
在文章开头我们就提到反射的一大好处就是可以允许我们在运行期间获取对象的类型信息,下面我们通过一个例子来具体看一下。
首先我们在typeinfo.interfacea包下面新建一个接口A:
packagetypeinfo.interfacea;
publicinterfaceA{voidf();}
接着我们在typeinfo.packageaccess包下面新建一个接口C,接口C继承自接口A,并且我们还另外创建了几个用于测试的方法,注意下面几个方法的权限都是不同的。
6. Java代理的作用和实现
JDK 动态代理
动态代理的核心其实就是代理对象的生成,即 Proxy.newProxyInstance(classLoader, proxyInterface, handler)。
让我们进入newProxyInstance方法观摩下,核心代码其实就三行。
这个方法需要三个参数:
ClassLoader,用于加载代理类的 Loader 类,通常这个 Loader 和被代理的类是同一个 Loader 类。
Interfaces,是要被代理的那些那些接口。
InvocationHandler,就是用于执行除了被代理接口中方法之外的用户自定义的操作,也是用户需要代理的最终目的。用户调用目标方法都被代理到 InvocationHandler 类中定义的唯一方法 invoke 中。
一个典型的动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建调用处理器
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
为了简化对象创建过程,Proxy类中的newProxyInstance方法封装了2~4,只需两步即可完成代理对象的创建。
生成的proxySubject继承Proxy类实现Subject接口。实现的Subject的方法实际是调用处理器的invoke方法,而invoke方法利用反射调用的是被代理对象的方法(Object result=method.invoke(proxied,args));
重点Proxy.newProxyInstance,源码分析,会在其他文档中单独总结记录。类Proxy的getProxyClass方法调用ProxyGenerator的 generateProxyClass方法产生ProxySubject.class的二进制数据。
创建代理对象时序图
获取代理类
getProxyClass(loader, interfaces)方法用于获取代理类,它主要做了三件事情:
在当前类加载器的缓存里搜索是否有代理类,没有则生成代理类并缓存在本地JVM里。
生成并加载代理类
代理类的生成主要是以下这两行代码:
代理类的生成过程
ProxyGenerator.generateProxyClass()方法属于sun.misc包下,Oracle并没有提供源代码,但是我们可以使用
JD-GUI这样的反编译软件打开jrelib
t.jar来一探究竟,以下是其核心代码的分析。
生成的代理类源码
那么通过以上分析,我们可以推出动态代理为我们生成了一个这样的代理类。把方法doSomeThing的方法体修改为调用LogInvocationHandler的invoke方法。
测试代理的代码如下:
下面看一个自定义代理的实现。
被代理类接口
被代理类
调用处理器(切面)
测试我们的代理实现
运行结果:
Proxy 接口
Proxy 的主要静态变量
ProxySubject 源码
创建的代理类 ProxySubject.class
CGLib 动态代理
动态字节码生成。使用动态字节码生成技术实现AOP原理是在运行期间目标字节码加载后,生成目标类的子类,将切面逻辑加入到子类中,所以使用Cglib实现AOP不需要基于接口。
7. java中的反射机制是什么有什么作用呢求解,谢谢。
1. 反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2. 反射机制能做什么
反射机制主要提供了以下功能:
在运行时判断任意一个对象所属的类;
在运行时构造任意一个类的对象;
在运行时判断任意一个类所具有的成员变量和方法;
在运行时调用任意一个对象的方法;
生成动态代理。
3. 反射机制的相关API
通过一个对象获得完整的包名和类名
packagenet.xsoftlab.ke;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
TestReflecttestReflect=newTestReflect();
System.out.println(testReflect.getClass().getName());
//结果net.xsoftlab.ke.TestReflect
}
}
实例化Class类对象
packagenet.xsoftlab.ke;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>class1=null;
Class<?>class2=null;
Class<?>class3=null;
//一般采用这种形式
class1=Class.forName("net.xsoftlab.ke.TestReflect");
class2=newTestReflect().getClass();
class3=TestReflect.class;
System.out.println("类名称"+class1.getName());
System.out.println("类名称"+class2.getName());
System.out.println("类名称"+class3.getName());
}
}
获取一个对象的父类与实现的接口
packagenet.xsoftlab.ke;
importjava.io.Serializable;
{
=-2862585049955236662L;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
//取得父类
Class<?>parentClass=clazz.getSuperclass();
System.out.println("clazz的父类为:"+parentClass.getName());
//clazz的父类为:java.lang.Object
//获取所有的接口
Class<?>intes[]=clazz.getInterfaces();
System.out.println("clazz实现的接口有:");
for(inti=0;i<intes.length;i++){
System.out.println((i+1)+":"+intes[i].getName());
}
//clazz实现的接口有:
//1:java.io.Serializable
}
}
获取某个类中的全部构造函数 - 详见下例
通过反射机制实例化一个类的对象
packagenet.xsoftlab.ke;
importjava.lang.reflect.Constructor;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>class1=null;
class1=Class.forName("net.xsoftlab.ke.User");
//第一种方法,实例化默认构造方法,调用set赋值
Useruser=(User)class1.newInstance();
user.setAge(20);
user.setName("Rollen");
System.out.println(user);
//结果User[age=20,name=Rollen]
//第二种方法取得全部的构造函数使用构造函数赋值
Constructor<?>cons[]=class1.getConstructors();
//查看每个构造方法需要的参数
for(inti=0;i<cons.length;i++){
Class<?>clazzs[]=cons[i].getParameterTypes();
System.out.print("cons["+i+"](");
for(intj=0;j<clazzs.length;j++){
if(j==clazzs.length-1)
System.out.print(clazzs[j].getName());
else
System.out.print(clazzs[j].getName()+",");
}
System.out.println(")");
}
//结果
//cons[0](java.lang.String)
//cons[1](int,java.lang.String)
//cons[2]()
user=(User)cons[0].newInstance("Rollen");
System.out.println(user);
//结果User[age=0,name=Rollen]
user=(User)cons[1].newInstance(20,"Rollen");
System.out.println(user);
//结果User[age=20,name=Rollen]
}
}
classUser{
privateintage;
privateStringname;
publicUser(){
super();
}
publicUser(Stringname){
super();
this.name=name;
}
publicUser(intage,Stringname){
super();
this.age=age;
this.name=name;
}
publicintgetAge(){
returnage;
}
publicvoidsetAge(intage){
this.age=age;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
@Override
publicStringtoString(){
return"User[age="+age+",name="+name+"]";
}
}
获取某个类的全部属性
packagenet.xsoftlab.ke;
importjava.io.Serializable;
importjava.lang.reflect.Field;
importjava.lang.reflect.Modifier;
{
=-2862585049955236662L;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
System.out.println("===============本类属性===============");
//取得本类的全部属性
Field[]field=clazz.getDeclaredFields();
for(inti=0;i<field.length;i++){
//权限修饰符
intmo=field[i].getModifiers();
Stringpriv=Modifier.toString(mo);
//属性类型
Class<?>type=field[i].getType();
System.out.println(priv+""+type.getName()+""+field[i].getName()+";");
}
System.out.println("==========实现的接口或者父类的属性==========");
//取得实现的接口或者父类的属性
Field[]filed1=clazz.getFields();
for(intj=0;j<filed1.length;j++){
//权限修饰符
intmo=filed1[j].getModifiers();
Stringpriv=Modifier.toString(mo);
//属性类型
Class<?>type=filed1[j].getType();
System.out.println(priv+""+type.getName()+""+filed1[j].getName()+";");
}
}
}
通过反射机制调用某个类的方法
packagenet.xsoftlab.ke;
importjava.lang.reflect.Method;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
//调用TestReflect类中的reflect1方法
Methodmethod=clazz.getMethod("reflect1");
method.invoke(clazz.newInstance());
//Java反射机制-调用某个类的方法1.
//调用TestReflect的reflect2方法
method=clazz.getMethod("reflect2",int.class,String.class);
method.invoke(clazz.newInstance(),20,"张三");
//Java反射机制-调用某个类的方法2.
//age->20.name->张三
}
publicvoidreflect1(){
System.out.println("Java反射机制-调用某个类的方法1.");
}
publicvoidreflect2(intage,Stringname){
System.out.println("Java反射机制-调用某个类的方法2.");
System.out.println("age->"+age+".name->"+name);
}
}
通过反射机制操作某个类的属性
packagenet.xsoftlab.ke;
importjava.lang.reflect.Field;
publicclassTestReflect{
privateStringproprety=null;
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Class.forName("net.xsoftlab.ke.TestReflect");
Objectobj=clazz.newInstance();
//可以直接对private的属性赋值
Fieldfield=clazz.getDeclaredField("proprety");
field.setAccessible(true);
field.set(obj,"Java反射机制");
System.out.println(field.get(obj));
}
}
4. 反射机制的应用实例
在泛型为Integer的ArrayList中存放一个String类型的对象。
packagenet.xsoftlab.ke;
importjava.lang.reflect.Method;
importjava.util.ArrayList;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
ArrayList<Integer>list=newArrayList<Integer>();
Methodmethod=list.getClass().getMethod("add",Object.class);
method.invoke(list,"Java反射机制实例。");
System.out.println(list.get(0));
}
}
通过反射取得并修改数组的信息
packagenet.xsoftlab.ke;
importjava.lang.reflect.Array;
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
int[]temp={1,2,3,4,5};
Class<?>demo=temp.getClass().getComponentType();
System.out.println("数组类型:"+demo.getName());
System.out.println("数组长度"+Array.getLength(temp));
System.out.println("数组的第一个元素:"+Array.get(temp,0));
Array.set(temp,0,100);
System.out.println("修改之后数组第一个元素为:"+Array.get(temp,0));
}
}
将反射机制应用于工厂模式
packagenet.xsoftlab.ke;
interfacefruit{
publicabstractvoideat();
}
classAppleimplementsfruit{
publicvoideat(){
System.out.println("Apple");
}
}
classOrangeimplementsfruit{
publicvoideat(){
System.out.println("Orange");
}
}
classFactory{
publicstaticfruitgetInstance(StringClassName){
fruitf=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch(Exceptione){
e.printStackTrace();
}
returnf;
}
}
/**
*对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。当我们添加很多的子类的时候,会很麻烦。
*Java工厂模式可以参考
*http://ke.xsoftlab.net/view/java-factory-pattern
*
*现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
*
*但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
*
*java读取properties配置文件的方法可以参考
*http://ke.xsoftlab.net/view/java-read-the-properties-configuration-file
*
*@authorxsoftlab.net
*/
publicclassTestReflect{
publicstaticvoidmain(String[]args)throwsException{
fruitf=Factory.getInstance("net.xsoftlab.ke.Apple");
if(f!=null){
f.eat();
}
}
}
我有一个微信公众号,经常会分享一些Java技术相关的干货,还有一些学习资源。
如果你喜欢我的分享,可以用微信搜索“Java团长”或者“javatuanzhang”关注。