从零开始学java (四)反射
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Class 类 ,一个Class对象将表示一个类的属性;获取Class类一共有三种方式如下
package javase.first;
/**
* @author fqh
* @Date 2017年4月12日:上午8:15:01
*/
public class Employee {
//属性,私有化属性,并提供方法让其能够通过方法访问
private String name;
private int age;
private double salary;
private static final int NUMBER=217; //常量
private static void method1(){
System.out.println("静态方法");
}
static{
System.out.println("静态块");
}
public Employee(){
}
//构造器
public Employee(String name,int age,double salary){
this.name=name;
this.age=age;
this.salary=salary;
System.out.println("构造器");
}
public void raiseSalary(double multiple){
this.salary *= multiple;
}
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 double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
}
@Test
public void testReflect() {
Employee e =new Employee("fqh", 23, 5000);
Class class1 = null;
Class class2 = null;
Class class3 = null;
try {
//推荐这种
class1 = Class.forName("javase.first.Employee");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
//第二种
class2=Employee.class;
//第三种
class3=e.getClass();
System.out.println(class1.getName()+" "+e.getName());//通过Class。getName()可以获取类名
System.out.println(class2.getName()+" "+e.getName());//通过Class。getName()可以获取类名
System.out.println(class3.getName()+" "+e.getName());//通过Class。getName()可以获取类名
}
例如加载jdbc驱动的时候Class.forName("com.mysql.jdbc.Driver");
假如我需要获取类的属性方法等等,该怎么做呢?
@Test
public void testReflect2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchFieldException {
Class class1 = null;
try {
//推荐这种
class1 = Class.forName("javase.first.Employee");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
System.out.println(class1.getName());//通过Class。getName()可以获取类名
System.out.println("===============本类属性===============");
//获取所有属性 ,getFields()是获取所有公有的方法
Field[] fields =class1.getDeclaredFields();
for(Field f:fields)
{
// 权限修饰符
int mo = f.getModifiers();
String priv = Modifier.toString(mo);
// 属性类型
Class<?> type = f.getType();
System.out.println(priv + " " + type.getName() + " " + f.getName() + ";");
}
System.out.println("===============本类方法===============");
Method[] methods =class1.getDeclaredMethods();
for(Method f:methods)
{
// 权限修饰符
int mo = f.getModifiers();
String priv = Modifier.toString(mo);
// 属性类型
Class<?> type = f.getReturnType();
System.out.println(priv + " " + type.getName() + " " + f.getName() + ";");
}
System.out.println("===============通过反射机制调用方法===============");
Object obj = class1.newInstance();
Method method = class1.getMethod("setName", String.class);
method.invoke(obj,"fqh");
method = class1.getMethod("getName");
method.invoke(obj);
Employee e = (Employee) obj ;
System.out.println(e.getName());
System.out.println("===============通过反射机制修改属性===============");
Field field =class1.getDeclaredField("name");
// 可以直接对 private 的属性赋值
field.setAccessible(true);//将属性设为可修改
field.set(obj, "Java反射机制");
System.out.println(field.get(obj));
}
将反射应用在工厂方法
interface fruit {
public abstract void eat();
}
class Apple implements fruit {
public void eat() {
System.out.println("Apple");
}
}
class Orange implements fruit {
public void eat() {
System.out.println("Orange");
}
}
class Factory {
public static fruit getInstance(String ClassName) {
fruit f = null;
try {
f = (fruit) Class.forName(ClassName).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
/**
* 对于普通的工厂模式当我们在添加一个子类的时候,就需要对应的修改工厂类。 当我们添加很多的子类的时候,会很麻烦。
* Java 工厂模式可以参考
* http://baike.xsoftlab.net/view/java-factory-pattern
*
* 现在我们利用反射机制实现工厂模式,可以在不修改工厂类的情况下添加任意多个子类。
*
* 但是有一点仍然很麻烦,就是需要知道完整的包名和类名,这里可以使用properties配置文件来完成。
*
* java 读取 properties 配置文件 的方法可以参考
* http://baike.xsoftlab.net/view/java-read-the-properties-configuration-file
*
* @author xsoftlab.net
*/
public class TestReflect {
public static void main(String[] args) throws Exception {
fruit f = Factory.getInstance("net.xsoftlab.baike.Apple");
if (f != null) {
f.eat();
}
}
}
从零开始学java (四)反射的更多相关文章
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(二)
Memcached 客户端选择 上一篇文章 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)中我们讲到这篇要谈客户端的选择,在 Java 中一般常用的有三个: Memc ...
- 从零开始学 Java - 利用 Nginx 负载均衡实现 Web 服务器更新不影响访问
还记得那些美妙的夜晚吗 你洗洗打算看一个小电影就睡了,这个时候突然想起来今天晚上是服务器更新的日子,你要在凌晨时分去把最新的代码更新到服务器,以保证明天大家一觉醒来打开网站,发现昨天的 Bug 都不见 ...
- 从零开始学 Java - Spring AOP 实现用户权限验证
每个项目都会有权限管理系统 无论你是一个简单的企业站,还是一个复杂到爆的平台级项目,都会涉及到用户登录.权限管理这些必不可少的业务逻辑.有人说,企业站需要什么权限管理阿?那行吧,你那可能叫静态页面,就 ...
- 从零开始学 Java - Spring AOP 实现主从读写分离
深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写 ...
- 从零开始学 Java - CentOS 下安装 Nginx
早上下起了暴雨 闹钟还未响起就听到雨滴哗啦啦击打窗户的声音,被吵醒了.起床上班,在楼下的十字路口,暴雨大到完全看不清对面,两个穿着雨衣的交警站在路口中间指挥着过往的车辆,大家都慌慌张张.急急忙忙的打着 ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(一)
你家小区下面有没有快递柜 近两年来,我们收取快递的方式好像变了,变得我们其实并不需要见到快递小哥也能拿到自己的快递了.对,我说的就是类似快递柜.菜鸟驿站这类的代收点的出现,把我们原来快递小哥必须拿着快 ...
- 从零开始学 Java - Spring 集成 Memcached 缓存配置(一)
硬盘和内存的作用是什么 硬盘的作用毫无疑问我们大家都清楚,不就是用来存储数据文件的么?如照片.视频.各种文档或等等,肯定也有你喜欢的某位岛国老师的动作片,这个时候无论我们电脑是否关机重启它们永远在那里 ...
- 从零开始学 Java - 我放弃了 .NET ?
这不是一篇引起战争的文章 毫无疑问,我之前是一名在微软温暖怀抱下干了近三年的 .NET 开发者,为什么要牛(sha)X一样去搞 Java 呢?因为我喜欢 iOS 阿!哈哈,开个玩笑.其实,开始学 Ja ...
- 从零开始学 Java - Spring 集成 ActiveMQ 配置(二)
从上一篇开始说起 上一篇从零开始学 Java - Spring 集成 ActiveMQ 配置(一)文章中讲了我关于消息队列的思考过程,现在这一篇会讲到 ActivMQ 与 Spring 框架的整合配置 ...
- 从零开始学 Java - log4j 项目中的详细配置
你还会用笔来写字么 我是不怎么会了,有时候老是拿起笔之后不知道这个字怎么写,这时候就会拿起手机去打出来:有时候还会写出来这个字之后越看越不像,这时候就开始怀疑自己的能力了:有时候写出来了一大堆字之后, ...
随机推荐
- 基于SpringBoot+Mybatis+AntDesign快速开发平台,Jeecg-Boot 1.1 版本发布
Jeecg-Boot 1.1 版本发布,初成长稳定版本 导读 平台首页UI升级,精美的首页支持多模式 提供4套代码生成器模板(支持单表.一对多) 集成Excel简易工具类,支持单表.一对多导入 ...
- GDI+_从Bitmap里得到的Color数组值分解
[这里写只是我个人的摸索经历,已经给出解决方案] 我之前写过一篇关于ARGB值的研究:https://www.cnblogs.com/lingqingxue/p/10362639.html 最近我又遇 ...
- 【原创】qlogic网卡软中断不均衡问题分析
引子 使用qlogic QL45000网卡测试业务性能,发现cpu软中断分布不均衡,而且很有规律,导致cpu空闲也不是很均衡, 会影响业务稳定性. 设备使用3张网卡Qlogic网卡,配置为4*25G模 ...
- k8s重启策略
Pod 的重启策略有 3 种,默认值为 Always. Always : 容器失效时,kubelet 自动重启该容器: OnFailure : 容器终止运行且退出码不为0时重启: Never : 不论 ...
- vue mock
如果后端不肯来帮你 mock 数据的话,前端自己来 mock 也是很简单的.你可以使用mock server 或者使用 mockjs + rap 也是很方便的. 不久前出的 easy-mock也相当的 ...
- Linux中文乱码 - - 更改Linux字符集
查看当前系统默认采用的字符集: # locale 在RedHat/CentOS系统下,记录系统默认使用语言的文件是/etc/sysconfig/i18n,如果默认安装的是中文的系统,i18n的内容如 ...
- Apache Flink 分布式运行时环境
Tasks and Operator Chains(任务及操作链) 在分布式环境下,Flink将操作的子任务链在一起组成一个任务,每一个任务在一个线程中执行.将操作链在一起是一个不错的优化:它减少了线 ...
- Android Toast 工具类
android 中常用系统吐司工具类 package cn.yhq.utils; import android.content.Context; import android.widget.Toas ...
- SQL数据库索引理解与应用【转贴--收藏】
SQL数据库中索引分为聚集索引(CLUSTERED)和非聚集索引(NONCLUSTERED)两种. 聚集索引确定表中数据的物理顺序,它就类似与电话簿,按照姓氏排列数据.由于聚集索引规定数据表中的物理顺 ...
- 解决time_wait过多
需要真正找出问题或瓶颈,但调整单机参数能临时解决:(收集自:https://www.cnblogs.com/dadonggg/p/8778318.html) 编辑内核文件/etc/sysctl.con ...