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当中的反射的更多相关文章

  1. java中的反射

    1.何为java反射机制: 在运行过程中,对于任意一个类都能够知道这个类的属性和方法:对于任意一个对象都能调用其属性和方法:这种动态获取信息和动态调用方法 就称为java反射 2.获取Class对象的 ...

  2. 谈一谈java里面的反射机制

    首先来看看百度百科中是如何定义的: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方 ...

  3. Java中的反射和注解

    前言 在Java中,反射机制和注解机制一直是一个很重要的概念,那么他们其中的原理是怎么样呢,我们不仅仅需要会使用,更要知其然而之所以然. 目录 反射机制 反射如何使用 注解定义 注解机制原理 注解如何 ...

  4. java中的反射机制在Android开发中的用处

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

  5. Java里面,反射父类里面数字类型字段,怎么set值

    Java里面,反射父类里面数字类型字段,怎么set值,我的做法是这样: /** * TODO 直接设置对象属性值, 忽略private/protected 修饰符, 也不经过setter * @aut ...

  6. java 27 - 2 反射之 反射的概述以及获取Class文件对象的方式

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

  7. Java当中的内存分配以及值传递问题内存解析

    首先必须说明作为Java程序员对于内存只要有大致的了解就可以了,如果你对Java当中的某一个知识点在不需要分析内存分配过程的情况下可以掌握,那就大可不必去研究内存.如果你对知识点已经掌握,那么你应该把 ...

  8. 黑马程序员——【Java高新技术】——反射机制

    ---------- android培训.java培训.期待与您交流! ---------- 一.概述 1.Java反射机制:是指“在运行状态中”,对于任意一个类,都能够知道这个类中的所有属性和方法: ...

  9. Java 中的反射机制

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

随机推荐

  1. 群晖SVN Server远程访问

    打开路由器访问界面 选择转发规则->端口映射-新建 在弹出的界面中填写相应的端口号了内网ip 填写svn所在地址的IP,比如:192.168.30.2 添加映射端口,比如svn的默认端口是330 ...

  2. IOS的MVC和MVVM模式简明介绍

    iOS中的MVC(Model-View-Controller)将软件系统分为Model.View.Controller三部分,结构图如下: Model: 你的应用本质上是什么(但不是它的展示方式) C ...

  3. windows系统IIS环境下如何部署MVC项目

    首先打开IIS:第一步:添加MVC程序映射 打开其中的:处理程序映射,如下图: 点击界面右边操作中的:添加脚本映射,弹出下图: 请求路径:*           可执行文件:c:/Windows/Mi ...

  4. LeetCode Intersection of Two Arrays II

    原题链接在这里:https://leetcode.com/problems/intersection-of-two-arrays-ii/ 题目: Given two arrays, write a f ...

  5. Python之路----------shutil模块

    高级的文件.文件夹.压缩包 处理模块 复制文件: import shutil f1 = open('test') f2 = open('test2','w') shutil.copyfileobj(f ...

  6. Python模块和包

    模块和包是python组织代码的基本方式. 模块: python的每一个脚本文件都可称之为模块,模块的名称就是脚本的文件名.例如当我们写了一个test.py的脚本文件,则可以在同目录下的另外一个脚本m ...

  7. C语言第7次作业

    1 #include<stdio.h> int main() { char name[50];int character[26]={0};int i=0,j;int length=0;wh ...

  8. 浅析angular,react,vue.js jQuery使用区别

    前端越来越混乱了,当然也可以美其名曰:繁荣.当新启动一个前端项目,第一件事就是纠结:使用什么框架,重造什么轮子? PS:大牛留言讨论那么,希望看完此篇,能够给你一个清晰的认识,或者让你更加地纠结和无所 ...

  9. linux昨天修改的文件

    find ./ -mtime :返回最近24小时内修改过的文件. find ./ -mtime : 返回的是前48~24小时修改过的文件.而不是48小时以内修改过的文件. Linux查找文件内容的常用 ...

  10. Overview of the Oppia codebase(Oppia代码库总览)

    Oppia is built with Google App Engine. Its backend is written in Python, and its frontend is written ...