Java当中的反射
1:反射的概念
反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
2:反射的作用
可以说,实现了反射机制的系统都具有开放性,但具有开放性的系统并不一定采用了反射机制,开放性是反射系统的必要条件。一般来说,反射系统除了满足开放性条件外还必须满足原因连接(Causally-connected)。所谓原因连接是指对反射系统自描述的改变能够立即反映到系统底层的实际状态和行为上的情况,反之亦然。开放性和原因连接是反射系统的两大基本要素.
举个例子:在做项目的过程中,可能会遇到数据库变化,当然是一次使用一个数据库的时候,而可能要在两个数据库之间切换,就可以在config文件中根据关键属性的设置即可,根据反射实例不同的对象,而其他操作数据库的代码不需要改变,当然前提是你已经为两个数据库写好不同的操作的代码,这样就可以实现系统的开放性,一个实例如此,可能有人会说,那我根据字符串判断生成不同的对象就可以了呀,当然可以,但是如果需要根据配置文件同时实例多个不同的对象的话,而配置文件是可以动态变化的,这样就可以实现更好的开放性
3:反射机制中的类:
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
4:获取字节码文件对象(Person.class)的三种方式
package reflect; public class Demo1
{
/* 1:使用Object类提供的Class getClass()方法,获取字节码文件对象
* 需要先创建对象
*
* 2:每个数据类型都有一个静态的属性class, 这个属性返回的是该数据类型所属的字节码文件对象
* 需要这个类事先存在
* String.class int.class
*
* 3:使用 Class类中的Class forName(String str)方法
* 只需要提供一个字符串,字符串中指明包名和类名
*
*/
public static void main(String[] args) throws ClassNotFoundException
{
getClass3();
} // 使用 Class类中的Class forName(String str)方法
public static void getClass3() throws ClassNotFoundException
{
Class<?> cla = Class.forName("reflect.Person");
Class<?> cla2 = Class.forName("reflect.Person");
System.out.println(cla == cla2);
} // 静态的属性class
public static void getClass2()
{
Class<Person> cla = Person.class;
Class<Person> cla2 = Person.class;
System.out.println(cla == cla2);
} // 使用Object类提供的Class getClass()方法
public static void getClass1()
{
Person person = new Person();
Class<? extends Person> cla = person.getClass();
Person person2 = new Person();
Class<? extends Person> cla2 = person.getClass();
System.out.println(cla == cla2);
}
}
5:字节码文件对象Class对象的使用(重点)
java.lang.reflect.Constructor ==》 动态获取类并创建对象
- 我们知道创建对象必须要用到构造函数,无法使用Person类来new一个对象,我们如何通过字节码文件对象创建一个Person类的对象?
- 那就要就要用用newInstance方法了,如果是无参的,就用Class对象的newInstance方法,如果是有参的,就用Class对象创建的构造函数的对象的newInstance方法..
package reflect; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; public class Demo2
{
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, IllegalArgumentException, SecurityException, InvocationTargetException, NoSuchMethodException
{
createObj2();
}
//使用带参数的构造方法创建对象
public static void createObj2() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException
{
//获取字节码文件对象---Person.class
Class<?> claz = Class.forName("reflect.Person");
//获取带参数的构造方法所属的Constructor类型的对象
Constructor<?> con = claz.getConstructor(String.class, int.class,
String.class);
//使用Constructor类提供的创建对象的方法
Person person = (Person) con.newInstance("李鹏", 21, "男"); System.out.println(person);
} // 使用空参的构造方法创建对象
// newInstance()使用的是空参数的构造方法创建对象,所以但空参的构造方法不存在时会发生InstantiationException
// 当空参的构造方法的权限比较低的时候,会发生 IllegalAccessException
public static void createObj1() throws ClassNotFoundException,
InstantiationException, IllegalAccessException
{
Class claz = Class.forName("reflect.Person");
Person p = (Person) claz.newInstance();//默认使用的是空参数的构造方法创建的对象
System.out.println(p);
}
}
java.lang.reflect.Field==》动态创建对象并给对象的属性赋值;
package reflect; import java.lang.reflect.Field; public class Demo3
{
public static void main(String[] args) throws ClassNotFoundException,
SecurityException, NoSuchFieldException, InstantiationException,
IllegalAccessException
{
Class claz = Class.forName("reflect.Person"); // 获取属性所属的Field类型的对象
// Field field = claz.getField("name");//只能获取public权限的属性
Field field = claz.getDeclaredField("name");// 可以获取任何权限的属性 Person person = (Person) claz.newInstance(); // 设置name为可访问的,如果属性原来的是私有的,这句话必不可少
field.setAccessible(true); field.set(person, "李鹏");// 给name属性赋值 System.out.println(person);
}
}
java.lang.reflect.Method==》动态创建对象,并调用其方法;
package reflect; import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; public class Demo4
{
public static void main(String[] args) throws IllegalArgumentException, SecurityException, InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException
{
method3();
}
//调用静态方法
public static void method3() throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, NoSuchMethodException
{
Class claz = Class.forName("reflect.Person"); //Person p = (Person) claz.newInstance(); Method method = claz.getMethod("fun", null); method.invoke(null, null);//这里的第一个参数可以使null,可以是对象..
}
//调用带参数的方法
public static void method2() throws ClassNotFoundException, InstantiationException, IllegalAccessException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException
{
Class claz = Class.forName("reflect.Person"); Person p = (Person) claz.newInstance(); Method method = claz.getMethod("say", String.class,int.class); method.invoke(p,"哈哈",3); }
//调用无参的方法
public static void method1() throws IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException, SecurityException, NoSuchMethodException, ClassNotFoundException
{
Class claz = Class.forName("reflect.Person"); Constructor con = claz.getConstructor(String.class,int.class,String.class); Person person = (Person) con.newInstance("李鹏",21,"男"); //使用Person的Class对象得到被调用的方法所属的Method类型的对象
Method m = claz.getMethod("show", null); //使用 Method对象的invoke()方法执行
m.invoke(person, null);
}
}
6:反射的应用==》实现根据配置文件实现自定义不同接口的启动
package reflect; interface USB
{
public abstract void open();
public abstract void close();
}
USB接口
package reflect; public class MouseUsb implements USB
{ @Override
public void close()
{
System.out.println("mouse close");
} @Override
public void open()
{
System.out.println("mouse open");
} }
MouseUsb
package reflect; public class KeyUsb implements USB
{ @Override
public void close()
{
System.out.println("Key Close"); } @Override
public void open()
{
System.out.println("Key open"); } }
KeyUsb
package reflect; public class NoteBook
{
public void run()
{
System.out.println("笔记本运行了!");
} public void usbRun(USB usb)
{
if (usb != null)
usb.open();
}
}
NoteBook
package reflect; import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties; public class Test
{ public static void main(String[] args) throws IOException,
ClassNotFoundException, InstantiationException,
IllegalAccessException
{
NoteBook nb = new NoteBook();
nb.run();
Properties pro = new Properties();
FileInputStream fis = new FileInputStream("config.properties"); pro.load(fis); for (int i = 1; i <= pro.size(); i++)
{
String value = pro.getProperty("usb" + i);
if (value != null)
{
Class<?> claz = Class.forName(value); USB usb = (USB) claz.newInstance(); nb.usbRun(usb);
}
} }
}
Client
Java当中的反射的更多相关文章
- java中的反射
1.何为java反射机制: 在运行过程中,对于任意一个类都能够知道这个类的属性和方法:对于任意一个对象都能调用其属性和方法:这种动态获取信息和动态调用方法 就称为java反射 2.获取Class对象的 ...
- 谈一谈java里面的反射机制
首先来看看百度百科中是如何定义的: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方 ...
- Java中的反射和注解
前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...
- java中的反射机制在Android开发中的用处
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反 ...
- Java里面,反射父类里面数字类型字段,怎么set值
Java里面,反射父类里面数字类型字段,怎么set值,我的做法是这样: /** * TODO 直接设置对象属性值, 忽略private/protected 修饰符, 也不经过setter * @aut ...
- java 27 - 2 反射之 反射的概述以及获取Class文件对象的方式
反射: JAVA语言的反射机制: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意一个方法和属性: 这种动态获取的信息以及动态调 ...
- Java当中的内存分配以及值传递问题内存解析
首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...
- 黑马程序员——【Java高新技术】——反射机制
---------- android培训.java培训.期待与您交流! ---------- 一.概述 1.Java反射机制:是指“在运行状态中”,对于任意一个类,都能够知道这个类中的所有属性和方法: ...
- Java 中的反射机制
JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
随机推荐
- DotNetBar grid筛选 按时间筛选
PatientDiaryPanel.Columns["RECORDDATE"].FilterExpr = string.Format("date(RECORDDATE) ...
- yii2.0场景的使用
- JAVA中使用FTPClient上传下载
Java中使用FTPClient上传下载 在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在c ...
- Qt容器类——1. QList类、QLinkedList类和QVector类
在开发一个较高性能需求的应用程序时,程序员会比较关注这些容器类的运行效率,表2.1列出了QList.QLinkedList和QVector容器的时间复杂度比较. 1.QList类 QList<T ...
- 随手记一次用C#正则表达式获取下拉菜单html标签<select>以及相关属性值
随手记一次用C#正则表达式获取下拉菜单html标签<select>以及相关属性值 1:有如下html: .................. <select id="aaa ...
- :active 为什么在ios上失效
:active是针对鼠标,而手机上是没有鼠标,而是touchstart,所以早成了ios上不兼容 解决方法是: window.onload = function(){ document.body.ad ...
- varnish4.1 配置文件default.vcl
varnish4.1 配置文件default.vcl # This .x VCL file vcl 4.0; backend default { .host = "127.0.0.1&quo ...
- simple mail example for smtp debug
vim /etc/mail.rc head /etc/rc.local | mail -s "test_email" pyz_sub1@mailtest.com
- 常用的Linux命令
1.如何创建一个目录?mkdir DirectoryName 2.如何进入服务器根目录?ls / 3.如何查看日历?cal 4.如何修改密码?passwd 5.如何查看当前用户信息?whoami 6. ...
- Win8+VMware12+CentOS7网络设置
VMware提供了三种将虚拟网卡和物理网卡捆绑起来的方式,即桥接(Bridge)模式,网络地址转换(Network Address Transformation, NAT)模式和主机(Host Onl ...