JAVA反射机制

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。
 

功能

Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
 
代码演示

package com.svse.reflex;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
import org.junit.Test;
/***
* 类的反射
* @author Administrator
* java反射机制提供的功能
* 在运行时:
* <1>判断任意一个对象所属的类
* <2>构造任意一个类的对象
* <3>判断任意一个类所具有的成员变量和方法
* <4>调用任意一个对象的成员变量和方法
* <5>生成动态代理
*/
public class ClassReflex {

//关于类的加载器classLoader
@Test
public void test5() throws ClassNotFoundException, IOException{
ClassLoader classLoader=ClassLoader.getSystemClassLoader();
System.out.println(classLoader);

ClassLoader classLoader1=classLoader.getParent();
System.out.println(classLoader1);

ClassLoader classLoader2=classLoader1.getParent();
System.out.println(classLoader2);

Class clazz=Person.class;
ClassLoader classLoader3=clazz.getClassLoader();
System.out.println(classLoader3);

String forName="java.lang.String";
Class clazz2=Class.forName(forName);
ClassLoader classLoader4=clazz2.getClassLoader();
System.out.println(classLoader4);

ClassLoader classLoader5=this.getClass().getClassLoader();
InputStream is=classLoader5.getResourceAsStream("com\\svse\\reflex\\db.properties");//读取properties文件信息
Properties properties=new Properties();
properties.load(is);
String name=properties.getProperty("name");
String password=properties.getProperty("password");
System.out.println(name+" : "+password);

}

/***
* 获取class实例的三种方式
* @throws ClassNotFoundException
*/
@Test
public void test4() throws ClassNotFoundException{
//1:调用运行时类本身的class属性
Class clazz=Person.class;
System.out.println(clazz.getName());
Class clazz2=String.class;
System.out.println(clazz2.getName());
//2:通过运行时类的对象获取
Person p=new Person();
Class clazz3=p.getClass();
System.out.println(clazz3.getName());
//3:通过class的静态方法获取 (体会一下反射的动态性)
String forName="com.svse.reflex.Person";
Class clazz4=Class.forName(forName);
System.out.println(clazz.getName());

//4:了解类的加载器classLoader
ClassLoader classLoader=this.getClass().getClassLoader();
Class clazz5=classLoader.loadClass(forName);
System.out.println(clazz5.getName());

System.out.println(clazz==clazz2);
System.out.println(clazz==clazz3);
System.out.println(clazz==clazz4);
System.out.println(clazz==clazz5);

}

/**
* java.lang.Class 是反射的源头
* 通过运行时类的getClass()方法创建实例
*/
@Test
public void test3(){
Person p=new Person();
Class clazz=p.getClass();//通过运行时类的对象,调用其getClass()方法,返回其运行时类
System.out.println(clazz);
}

//有了反射之后,可以通过反射创建一个类的对象,并调用其中的属性和方法
@Test
public void test2() throws Exception{
Class clazz=Person.class;
//1创建clazz对应的运行时类person的对象
Person p=(Person) clazz.newInstance();
System.out.println(p);

//2 通过反射调用类的属性
Field f1=clazz.getField("name");
f1.set(p, "王小米");
System.out.println(p);
//Field f2=clazz.getField("age");
Field f2=clazz.getDeclaredField("age");//如果属性设置为private
f2.setAccessible(true);//必须设置允许访问为true,否则就获取不到私有属性的值
f2.set(p, 26);
System.out.println(p);
//3 通过反射调用类的方法
Method m1=clazz.getMethod("show");
m1.invoke(p);
Method m2=clazz.getMethod("display",String.class);
m2.invoke(p,"china");
//4

}

//在有反射前,传统的方法,如何创建一个类的对象,并调用其中的属性和方法
@Test
public void test1(){
Person p=new Person();
p.setAge(25);
p.setName("张三");
System.out.println(p);
p.show();
p.display("china");
}

}

db.properties文件

name=zhangsan
password=123456

Person.java文件

package com.svse.reflex;

public class Person {

public String name;
private int age;

public Person() {
super();
}

public Person(String name) {
super();
this.name = name;
}

public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}

public void add(String name){
System.out.println("公有的---"+name);
}

private void find(String name){
System.out.println("私有的---"+name);
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

public void show(){
System.out.println("我是一个man");
}
public void display(String nation){
System.out.println("我的国籍是:"+nation);
}

@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}

}

类的反射_reflex的更多相关文章

  1. JAVA进阶之旅(二)——认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践

    JAVA进阶之旅(二)--认识Class类,反射的概念,Constructor,Field,Method,反射Main方法,数组的反射和实践 我们继续聊JAVA,这次比较有意思,那就是反射了 一.认识 ...

  2. C#工具:反射帮助类 泛型反射帮助类

    反射帮助类 using System; using System.Reflection; using System.Data; using System.Drawing; using System.R ...

  3. 类的反射及xml文件的解析

    类的反射 xml文件的解析 .properties||.xml配置文件的创建及读取内容 //创建对象 Properties properties = new Properties(); //存储 pr ...

  4. python基础-类的反射

    1)反射是通过字符串方式映射内存中的对象. python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr, 改四个函数分别用于对对象内部执行:检查是 ...

  5. java--分析简单java类与反射的联系

    分析简单java类与反射的联系 web对反射的操作支持 在JSP之中有一种技术--javaBean.而且在jsp里面也配套有相应的操作方式,javaBean的核心在于简单java类,于是下面演示此操作 ...

  6. 类的反射实例(servlet的抽取)

    类的反射实例 具体以后我们写的时候不用写BaseServlet,因为各种框架都已经给我们写好了 所以,user对应的servlet的界面长这样:

  7. Java Class类及反射机制

    java.lang.Class类 声明: public final class Class<T>extends Object implements Serializable, Generi ...

  8. python(7)– 类的反射

    python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数分别用于对对象内部执行:检查是否含有某成员.获取成员.设置成员.删除成员. ...

  9. C# Assembly类_反射

    System.Reflection.Assembly类是一个比较常用到的类,在反射中就经常用到. 由于这个类实在有太多的字段.属性与方法.实在不想将一个个属性方法从MSDN复制出来然后逐个属性.方法敲 ...

随机推荐

  1. 面试:C++观察者模式实现

    #include <list> class Subject; class Observer{ public: virtual ~Observer(){}; virtual void upd ...

  2. h5活动页开发总结记录

    前几天在做h5活动页面的时候,有这样一个需求 上面的活动排行点击查看历史排行数据,弹出日期选择框,如下图 点击要查看的日期排行数据,这里需要对还没到的日期做处理,让用户不能选择,只可选择今天或者之前的 ...

  3. [转]Angular CLI 安装和使用

    本文转自:https://www.jianshu.com/p/327d88284abb 一. 背景介绍: 两个概念: 关于Angular版本,Angular官方已经统一命名Angular 1.x统称为 ...

  4. Docker版本变化和新版安装

    Docker从1.13版本之后采用时间线的方式作为版本号,分为社区版CE和企业版EE. 社区版是免费提供给个人开发者和小型团体使用的,企业版会提供额外的收费服务,比如经过官方测试认证过的基础设施.容器 ...

  5. EF 中多个数据库迁移

    Entity Framework 允许用户基于实体来创建和更新数据库,当项目中只有一个DBContext 时使用默认的参数就可以实现数据库的一些操作.当有多个DbContext 时需要制定参数才能完成 ...

  6. T-SQL:CTE用法(十)

    CTE 也叫公用表表达式和派生表非常类似 先定义一个USACusts的CTE WITH USACusts AS ( SELECT custid, companyname FROM Sales.Cust ...

  7. MVC 【ASPX视图引擎】

    新建项目----ASP.NET MVC 4 Web 应用程序------选择模板(空).视图引擎(ASPX) 1.认识控制器Controller using System; using System. ...

  8. hive 中date命令

  9. oracle sql优化的几种方法

    1.最基本最简单的方式是减少访问数据库的次数.oracle在内部执行了许多工作,比如解析SQL语句, 估算索引的利用率,  读数据块等等,都将大量耗费oracle数据库的运行 2.选择最有效率的表名顺 ...

  10. SpringCloud(二)Eureka集群与Feign

    两个Eureka 上一篇是两个服务像一个Eureka注册,如果Eureka宕掉了就不好了,现在来搭建两个Eureka,两个服务分别像其注册.两个Eureka都用本机来模拟,用两个端口号来表示. 首先修 ...