一、反射

1、反射概念

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

  要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。

2、Java 反射机制的主要用途

1、在运行时判断任意一个对象所属的类。

2、在运行时构造任意一个类的对象。

3、在运行时判断任意一个类所具有的成员变量和方法。

4、在运行时调用任意一个对象的方法。

3、三种获取Class实例对象的方式

1、Person p = new Person();

  Class c = p.getClass();

  已知类的对象,通过 getClass() 方法获取 Class 实例对象。

2、Class c2 = Person.class;

  任意数据类型都具备一个 class 静态成员变量,看上去要比第一种方式简单。

3、将类名作为字符串传递给Class类中的静态方法 forName 即可。

  Class c3 = Class.forName("Person");

 import com.reflect.pojo.Product;
import org.junit.Test; /**
* @author zt1994 2018/3/5 14:25
*/
public class TestReflect { /**
* 测试三种获取Class对象的方法
* @throws Exception
*/
@Test
public void testGetClass() throws Exception {
//实例化类的三种方法 任何对象都是Class的实例
//第一种 对象名.getClass()
Product product = new Product();
Class<? extends Product> aClass1 = product.getClass();
System.out.println(aClass1); //class com.reflect.pojo.Product
//第二种 类型.class
Class<Product> aClass2 = Product.class;
System.out.println(aClass2);
//第三种 Class 类中的静态方法 static Class<?>  forName(String className) className是类或者接口的权限定名
Class<?> aClass3 = Class.forName("com.reflect.pojo.Product");
System.out.println(aClass3);
//比较
System.out.println(aClass1==aClass2); //true
System.out.println(aClass1==aClass3); //true
System.out.println(aClass2==aClass3); //true
}
}

4、反射的作用

1、增加程序的灵活性,避免将程序写死到代码里(解除硬编码的问题);

2、Java的反射机制它知道类的基本结构,可以动态的去获取类这样的结构的结构;

3、可以让程序员在不知道其它程序员会有什么类的时候就编写完成自己的代码;

4、反射的优点:灵活,功能强大(可以拿到私有的....);

5、反射的缺点:破坏封装,影响性能;

5、反射运用(常用 API)

1、获取构造方法

getConstructors  不能获取私有的构造方法。

getDeclaredConstructors  可以获取所有构造方法,包括私有的。

  Product类:

 public class Product {
private Integer id;
private String productName;
private Integer classifyId;
private String brand; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getProductName() {
return productName;
} public void setProductName(String productName) {
this.productName = productName;
} public Integer getClassifyId() {
return classifyId;
} public void setClassifyId(Integer classifyId) {
this.classifyId = classifyId;
} public String getBrand() {
return brand;
} public void setBrand(String brand) {
this.brand = brand;
}
}

  获取构造方法:

   /**
* 测试获取构造方法
*/
@Test
public void testGetConstructor() throws ClassNotFoundException {
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
//获取构造器
Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("declaredConstructor: [" + declaredConstructor + "]");
}
}

2、反射创建对象

1、 newInstance()

注意 : 只能够调用无参数的构造方法,无参数的构造方法必须是有权限被访问到的。

2、获得构造器对象之后,通过构造器来创建对象

   /**
* 测试反射创建对象的两种方法
*/
@Test
public void testCreateInstance() throws Exception {
//方法一 Class类中有对应的方法 newInstance()
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
Product product = (Product) aClass.newInstance(); //方法二 获得构造器对象之后,通过构造器来创建对象
Constructor<?> constructor = aClass.getDeclaredConstructor();
Product product1 = (Product) constructor.newInstance();
}

3、获取方法

1、获取所有方法

  getMethods

  getDeclaredMethods

2、获取单个方法

  getMethod

  getDeclaredMethod

     /**
* 测试获取方法
*/
@Test
public void testGetMethods() throws Exception{
Class<?> aClass = Class.forName("com.reflect.pojo.Product"); //获取方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (int i = 0; i < declaredMethods.length; i++){
Method declaredMethod = declaredMethods[i];
//获取方法返回类型
Class<?> returnType = declaredMethod.getReturnType();
//输出方法返回类型
System.out.println("returnType: [" + returnType + "]");
//获取方法参数类型
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
for (Class parameterType: parameterTypes){
System.out.println("parameterType: [" + parameterType + "]");
}
//输出变量名称
System.out.println("i: " + i + " declaredMethod: ["+declaredMethod.getName() + "]");
}
}

4、获取字段(成员变量)

1、获取所有字段

  getFields、getDeclaredFields

2、获取单个字段

  getField、getDeclaredField

3、修改获取字段的值

  set(Object obj,Object value); 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。

  get(Object obj);  返回指定对象(传入的obj)上此 Field 表示的字段的值。

     /**
* 获取字段
*/
@Test
public void testAPI() throws ClassNotFoundException {
//获取field
Class<?> aClass = Class.forName("com.reflect.pojo.Product");
//获取字段
Field[] declaredFields = aClass.getDeclaredFields();
for (Field df:declaredFields){
//获取字段类型
Class<?> type = df.getType();
System.out.println("type: [" + type + "]");
System.out.println(df);
}
}

5、通过反射调用方法

1、获得类对应的Class实例;

2、通过反射得到类中的指定的方法

3、通过反射(Method类)来调用方法

Method中的方法:

Object invoke(Object obj, Object... args)

obj: 调用的对象

args: 方法参数

     /**
* 反射调用方法
*/
@Test
public void testInvoke() throws Exception {
Product product = new Product();
product.setId(7);
product.setClassifyId(3);
product.setBrand("联想");
product.setProductName("G480笔记本"); //1.获取字节码
Class<?> aClass = product.getClass();
//2.获取属性
Field[] declaredFields = aClass.getDeclaredFields();
//3.获取属性数组
for (Field declaredField : declaredFields) {
//获取属性名
String fieldName = declaredField.getName();
//回去get方法字符串名
String methodName = "get" + toMethodName(fieldName);
//通过方法名称使用反射获取方法对象
Method method = aClass.getMethod(methodName);
//执行方法
Object invoke = method.invoke(product);
//装换字符串类型
String s = String.valueOf(invoke);
System.out.println(fieldName + "=" + s);
}
}

Java基础(十三)反射的更多相关文章

  1. 黑马程序员:Java基础总结----反射

    黑马程序员:Java基础总结 反射   ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 反射 反射的基石:Class类 Class类代表Java类,它的各个实例对象又分别 ...

  2. Java基础之一反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  3. Java基础之—反射

    反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码))   一.反射的概述 JAVA反射机制是在运行状态中,对于任意一个类,都能够 ...

  4. JAVA基础知识|反射

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

  5. java基础之反射机制

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

  6. java基础(十一 )-----反射——Java高级开发必须懂的

    本文我们通过一个实际的例子来演示反射在编程中的应用,可能之前大家对反射的学习,仅仅是停留在概念层面,不知道反射究竟应用在哪,所以是一头雾水.相信通过这篇教程,会让你对反射有一个更深层次的认知. 概念 ...

  7. java基础之反射---重要

    java反射: 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)):   1:获取Class字节码文件对象的三种方式: /** ...

  8. 【Java基础】反射和注解

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

  9. java基础篇---反射机制

    一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...

  10. Java 基础总结--反射的基本操作

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

随机推荐

  1. POJ 1330 Nearest Common Ancestors(lca)

    POJ 1330 Nearest Common Ancestors A rooted tree is a well-known data structure in computer science a ...

  2. fdisk 磁盘分区

    .[root@test4 ~]# fdisk /dev/sda //对sda磁盘进行分区 Device contains neither a valid DOS partition table, no ...

  3. react学习之路-配制antd-mobile

    经过将近三个月的使用,现在终于在我老大的带领下做完了一个react的项目,感觉还可以,最大的不足就是,对于react中的很多的东西都是掺杂着jq使用来做的,这是最不满意的一点吧,但是开发进度很近,只能 ...

  4. redis删除指定前缀的缓存

    redis作为缓存服务器为MySQL数据库提供较高的防御性,对于一些数据的查询可以直接从缓存中可以进行查询. 但是,某些情况下,我们需要清除缓存. 以下场景: 公司经常做活动,每个活动都存在大量的数据 ...

  5. SpringMVC 的初理解

    项目中用到了jetty,springboot两种构建服务器的方式,jetty是一种嵌入式的方式,部署启动都很灵活,springboot最大的优点就是很多配置文件都自己集成好了,虽然用了这么多好的框架, ...

  6. ubuntu下面的某些软件安装

    1. python 下面的mysql驱动:不是在pip里面安装,执行下面命令 apt-get install python-mysqldb

  7. 4:Median of Two Sorted Arrays

    here are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...

  8. 简说LINUX 下chmod|chown|chgrp和用法和区别

    1.chgrp(改变文件所属用户组) chgrp 用户组    文件名    ###就是这个格了.如果整个目录下的都改,则加-R参数用于递归. 如:chgrp  -R    user  smb.con ...

  9. C#利用WebBrowser获取完整COOKIE

    代码: http://www.cnblogs.com/hsapphire/archive/2010/09/10/1823384.html http://blog.csdn.net/attilax/ar ...

  10. django notes 一:开篇

    公司 web 框架用的是 django, 以前没用过,打算这两周好好看看. 边学习边整理一下笔记,加深理解. 好像谁说过初学者更适合写入门级的教程,我觉得有一定道理. 高手写的教程有一定深度,不会写入 ...