一、概述

1.1、概述

反射的概念:

在Java中的反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;

对于任意一个对象,都能够调用它的任意一个方法;

这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制

二、反射的3种方式

2.1、3种方式

1.声明对象如Person p=new Person,通过对象的p.getClass()方法

2.每个类都有一个.class属性,通过Person.class属性

3.Class.fromName("类的全路径"),全路径包名.类名

2.2、示例

普通的JAVA类,经过了一些修改有私有的方法与公有的方法

package com.pb.entity;
public class Person
{
private String name; //姓名
private String gender;//性别
private int age; //年龄 public Person()
{
//公开无参数构造方法
System.out.println("公开无参数构造方法");
}
public Person(String name,String gender,int age)
{ //公开有参数构造方法
System.out.println("公开有参数构造方法");
this.name=name;
this.gender=gender;
this.age=age;
}
//私有构造方法
private Person(String name)
{
System.out.println("这是私有的只有name的构造方法:"+name);
}
//私有构造方法
private Person(String name,int age)
{
System.out.println("这是私有的只有name和age的构造方法:"+name+"...."+age);
} /*
getter、setter方法
*/
public void setName(String name)
{
this.name=name;
}
public String getName()
{
return this.name;
}
public void setGender(String gender)
{
this.gender=gender;
}
public String getGender()
{
return this.gender;
}
/*
静态方法
*/
public static void staticMethod()
{
System.out.println("这是一个staticMethod方法");
}
/*
私有化方法
*/
private void setAge(int age)
{
this.age=age;
}
private int getAge()
{
return this.age;
} /*
私有的方法
*/
private void test()
{
System.out.println("这是私有的test方法");
}
/*
私有的方法
*/
private void test(String name,String gender)
{
System.out.println("这是私有的有参数的方法"+name+"..."+gender);
} /*
自我介绍的方法
*/
public void show()
{
System.out.println("姓名:"+this.name+",性别:"+this.gender+",年龄:"+this.age);
}
}

测试类

package com.pb.demo1;
//导入类
import com.pb.entity.Person;
/*
反射的三种方式:
1.类.class
2.声明对象,对象.getClass()方法如Person p=new Person(); p.getClass();
3.Class.forName("类的全路径");
*/
class ReflectionDemo1
{
public static void main(String[] args) throws Exception
{
reflect_fun1();
System.out.println("=========================");
reflect_fun2();
System.out.println("=========================");
reflect_fun3();
System.out.println("=========================");
}
/*
类.class
*/
public static void reflect_fun1()
{ //获取类对象,得到一个Class对象
Class cla1=Person.class;
Class cla2=Person.class;
System.out.println(cla1==cla2);
}
/*
声明对象,对象.getClass()方法如Person p=new Person(); p.getClass();
*/
public static void reflect_fun2()
{
Person p1=new Person();
//通过对象的getClass()方法
Class cla1=p1.getClass(); Person p2=new Person();
Class cla2=p2.getClass();
System.out.println(cla1==cla2); }
/*
Class.forName("类的全路径");
*/
public static void reflect_fun3() throws Exception
{
Class cla1=Class.forName("com.pb.entity.Person");
System.out.println(cla1); }
}

三、获取构造方法、方法、属性

3.1、概述

构造方法:

  • 公开的指定:getConstructor("方法名",参数1.....参数n),如String.class,要与方法中顺序一至,没有参数可以不写
  • 所有公开:getConstructors();返回一个Constructor [] 数组
  • 所有:getDeclaredConstructors();返回一个Constructor [] 数组
  • 私有:getDeclaredConstructor("方法名",参数1.....参数n),

方法:

  • 公开的指定:getMethod("方法名",参数1.....参数n),如String.class,要与方法中顺序一至,没有参数可以不写
  • 所有公开:getMethods();返回一个Method[] 数组
  • 所有:getDeclaredMethods();返回一个Method[] 数组
  • 私有:getDeclaredMethod("方法名",参数1.....参数n),

属性:

  • 公开的指定:getField("方法名"),如String.class,要与方法中顺序一至,没有参数可以不写
  • 所有公开:getFields();返回一个Method[] 数组
  • 所有:getDeclaredFields();返回一个Method[] 数组
  • 私有:getDeclaredMethod("方法名",参数1.....参数n),

3.2、示例

package com.pb.demo1;

//导入类
import com.pb.entity.Person;
import java.lang.reflect.*; /*
获取公开构造方法
获取私有构造方法
获取公开的方法
获取私有的方法
*/
class ReflectionDemo1 {
public static void main(String[] args) throws Exception {
getObj_con1();
System.out.println("========================="); getObj_con2();
System.out.println("========================="); getObj_con3();
System.out.println("========================="); getObj_con4();
System.out.println("========================="); getObj_meth1();
System.out.println("========================="); getObj_meth2();
System.out.println("========================="); getField_meth1();
System.out.println("=========================");
} /*
* 获取公开构造方法
*/
public static void getObj_con1() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
// 获取无参数的构造方法
Constructor<Person> con = cla.getConstructor();
System.out.println(con);
// 获取指定参数的构造方法有3个参数的构造方法
Constructor<Person> cons = cla.getConstructor(String.class, String.class, int.class);
System.out.println(cons); } /*
* 获取私有构造方法
*/
public static void getObj_con2() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
//获取私有一个参数的构造方法
Constructor<Person> con1=cla.getDeclaredConstructor(String.class);
System.out.println(con1);
//获取私有2个参数的构造方法
Constructor<Person> con2=cla.getDeclaredConstructor(String.class,int.class);
System.out.println(con2);
} /*
* 获取全部公有构造方法
*/
public static void getObj_con3() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
Constructor [] cons=cla.getConstructors();
//遍历
for(Constructor c:cons)
{
System.out.println(c);
}
}
/*
* 获取全部构造方法包括私有
*/
public static void getObj_con4() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
Constructor [] cons=cla.getDeclaredConstructors();
//遍历
for(Constructor c:cons)
{
System.out.println(c);
}
} /*
* 获取公开的方法
*/
public static void getObj_meth1() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
//获取方法名为show的公开方法
Method m1=cla.getMethod("show");
System.out.println(m1);
//获取setName的方法
Method m2=cla.getMethod("setName", String.class);
System.out.println(m2); //获取所有公开的方法包括从Object中继承的方法
Method [] ms=cla.getMethods();
//遍历
for(Method m:ms)
{
System.out.println(m);
}
} /*
* 获取私有的方法
*/
public static void getObj_meth2() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
//获取指定的私有方法名字为test,有2个字符串参数
Method m1=cla.getDeclaredMethod("test", String.class,String.class);
System.out.println(m1);
//也可以获取SET和get方法
Method m2=cla.getDeclaredMethod("getAge");
System.out.println(m2);
//获取全部方法包含私有
Method [] ms=cla.getDeclaredMethods();
//遍历
for(Method m:ms)
{
System.out.println(m);
}
}
/*
* 获取属性
*/
public static void getField_meth1() throws Exception{
Class cla = Class.forName("com.pb.entity.Person");
//获取指定的属性
Field f1=cla.getDeclaredField("name");
System.out.println(f1);
//有公开的话直接cla.getField(name)
//获取所有属性
Field [] fs=cla.getDeclaredFields();
for(Field f:fs){
System.out.println(f);
} }
}

结果

public com.pb.entity.Person()
public com.pb.entity.Person(java.lang.String,java.lang.String,int)
=========================
private com.pb.entity.Person(java.lang.String)
private com.pb.entity.Person(java.lang.String,int)
=========================
public com.pb.entity.Person(java.lang.String,java.lang.String,int)
public com.pb.entity.Person()
=========================
public com.pb.entity.Person(java.lang.String,java.lang.String,int)
public com.pb.entity.Person()
private com.pb.entity.Person(java.lang.String)
private com.pb.entity.Person(java.lang.String,int)
=========================
public void com.pb.entity.Person.show()
public void com.pb.entity.Person.setName(java.lang.String)
public void com.pb.entity.Person.show()
public void com.pb.entity.Person.setGender(java.lang.String)
public java.lang.String com.pb.entity.Person.getGender()
public static void com.pb.entity.Person.staticMethod()
public java.lang.String com.pb.entity.Person.getName()
public void com.pb.entity.Person.setName(java.lang.String)
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
=========================
private void com.pb.entity.Person.test(java.lang.String,java.lang.String)
private int com.pb.entity.Person.getAge()
public void com.pb.entity.Person.show()
private int com.pb.entity.Person.getAge()
public void com.pb.entity.Person.setGender(java.lang.String)
public java.lang.String com.pb.entity.Person.getGender()
public static void com.pb.entity.Person.staticMethod()
private void com.pb.entity.Person.setAge(int)
public java.lang.String com.pb.entity.Person.getName()
public void com.pb.entity.Person.setName(java.lang.String)
private void com.pb.entity.Person.test(java.lang.String,java.lang.String)
private void com.pb.entity.Person.test()
=========================
private java.lang.String com.pb.entity.Person.name
private java.lang.String com.pb.entity.Person.name
private java.lang.String com.pb.entity.Person.gender
private int com.pb.entity.Person.age
=========================

四、创建对象

4.1、概述

两种创建对象的方式

  • 使用指定构造方法创建对象
  • 使用newIntance()创建对象,这个方法要求类必须有默认的构造方法,空参数构造方法

4.2、示例

package com.pb.demo1;
//导入类
import com.pb.entity.Person;
import java.lang.reflect.*;
public class ReflectDemo2 { public static void main(String[] args) throws Exception{
createObj1();
System.out.println("===============");
createObj2();
System.out.println("===============");
} /*
* 使用构造方法创建对象
*/
public static void createObj1() throws Exception {
Class cla = Class.forName("com.pb.entity.Person");
//获取指定的构造方法 3 个参数的参数方法
Constructor con=cla.getConstructor(String.class,String.class,int.class);
Person p=(Person) con.newInstance("张三","男",20);
p.show();
} /*
* 使用newInstance创建对象
*/
public static void createObj2() throws Exception {
Class cla = Class.forName("com.pb.entity.Person"); Person p=(Person) cla.newInstance();
p.show(); } }

结果:

公开有参数构造方法
姓名:张三,性别:男,年龄:20
===============
公开无参数构造方法
姓名:null,性别:null,年龄:0
===============

五、使用setter与getter

5.1、概述

invoke(Object obj, Object... args)
          对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

setAccessible(boolean flag)
          将此对象的 accessible 标志设置为指示的布尔值。

true表示可以设置,默认为false

只针对私有private修饰的需要设置

5.2、示例

package com.pb.demo1;
//导入类
import com.pb.entity.Person;
import java.lang.reflect.*;
/**
*
* 使用反射,调用setter与getter方法
*
*/
public class ReflectDemo3 { public static void main(String[] args)throws Exception {
setAndGet();
}
public static void setAndGet() throws Exception{
Class cla = Class.forName("com.pb.entity.Person");
//创建对象
Person p=(Person) cla.newInstance(); //获取setter方法
Method setName=cla.getMethod("setName", String.class);
//赋值,第一个参数是对象,第二个参数是要设置的值
setName.invoke(p, "张三");
Method setGender=cla.getMethod("setGender", String.class);
//赋值,第一个参数是对象,第二个参数是要设置的值
setGender.invoke(p, "女");
Method setAge=cla.getDeclaredMethod("setAge", int.class);
//因为是私有的把权限打开才开以赋值
setAge.setAccessible(true);
//赋值,第一个参数是对象,第二个参数是要设置的值
setAge.invoke(p, 32);
//获取show方法
Method show=cla.getMethod("show");
//调用方法
show.invoke(p);
//多个参数,可以写NULL,也可以不写返回一个Objec类,这个方法因为已经输出 } }

六、动态创建数组

6.1、概述

java.lang.reflect.Array

6.2、示例

/*
通过反射创建数组
创建一维数组或二维数组
1.通过Array.netInstance(类型.class,长度1,....长度n)
2.通过setXXX(数组名,下标,值)方法可以赋值
3.通过getXXX(数组名,下标)方法可以获取值
*/
import java.lang.reflect.*; class ReflectArray1
{
public static void main(String[] args)
{
createArray1();
System.out.println("=====================");
createArray2();
}
/*
反射创建一个String类型长度为10的一维数组
*/
public static void createArray1()
{
Object arr=Array.newInstance(String.class,10);
//为其中一些下标元素赋值
Array.set(arr,3,"hello");
Array.set(arr,5,"java");
Array.set(arr,7,"reflect");
Array.set(arr,8,"Array");
Array.set(arr,9,"!");
//获取值
Object o0=Array.get(arr,0);
Object o1=Array.get(arr,1);
Object o2=Array.get(arr,2);
Object o3=Array.get(arr,3); //下标为3的元素
Object o4=Array.get(arr,4);
Object o5=Array.get(arr,5);
Object o6=Array.get(arr,6);
Object o7=Array.get(arr,7);
Object o8=Array.get(arr,8);
Object o9=Array.get(arr,9); //强制转换
String [] str=(String[])arr;
for(String s:str)
{
System.out.println(s);
}
} /*
反射创建一个int类型长度为5,10的二维数组
*/
public static void createArray2()
{
Object arr=Array.newInstance(int.class,5,10);
//设置值
//获取一数组的下标
Object firstIndex1=Array.get(arr,3);
//为二维数组下标一个元素设置值
Array.setInt(firstIndex1,6,9); Object firstIndex2=Array.get(arr,1);
//为二维数组下标一个元素设置值
Array.setInt(firstIndex2,2,2);
//强转
int [] [] arrs=(int [] [])arr;
for(int x=0;x<arrs.length;x++)
{
for(int y=0;y<arrs[x].length;y++){
System.out.print(arrs[x][y]+",");
}
System.out.println();
} }
}


JAVA基础学习day27--反射机制的更多相关文章

  1. Java基础学习(1)——反射

    反射就是把Java类中的各种成分映射成相应的Java类(主要用于框架开发) 反射的基石–>Class类 Java程序中的各个类属于同一事物,描述这类事务的Java类名就是Class. Class ...

  2. 【java基础学习】反射

    1. 什么是反射 Class.Method.Field.Constructor,它们是反射对象.它们是类.方法.成员变量.构造器,在内存中的形式. 也就是万物皆对象!类是类型.方法是类型.成员变量是类 ...

  3. java学习之反射机制

    java语言区别于C,C++等准静态语言的最大特点就是java的反射机制.静态语言的最直接定义就是不能在运行时改变程序结构或变量的类型.按照这样的定义,python,ruby是动态语言,C,C++,J ...

  4. Java基础学习笔记总结

    Java基础学习笔记一 Java介绍 Java基础学习笔记二 Java基础语法之变量.数据类型 Java基础学习笔记三 Java基础语法之流程控制语句.循环 Java基础学习笔记四 Java基础语法之 ...

  5. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  6. Java基础教程:反射基础

    Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...

  7. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  8. [转帖]java基础学习总结——多态(动态绑定)

    https://www.cnblogs.com/xdp-gacl/p/3644035.html 多态的概念 java基础学习总结——多态(动态绑定) 一.面向对象最核心的机制——动态绑定,也叫多态

  9. Java基础学习-- 继承 的简单总结

    代码参考:Java基础学习小记--多态 为什么要引入继承? 还是做一个媒体库,里面可以放CD,可以放DVD.如果把CD和DVD做成两个没有联系的类的话,那么在管理这个媒体库的时候,要单独做一个添加CD ...

随机推荐

  1. mysql中int、bigint、smallint 和 tinyint的区别详细介绍

    1 bytes = 8 bit ,一个字节最多可以代表的数据长度是2的8次方 11111111 在计算机中也就是 -128到127 1.BIT[M] 位字段类型,M表示每个值的位数,范围从1到64,如 ...

  2. Raspberry Pi 3 Model B 安装 OSMC

    Raspberry Pi 3 Model B 自身搭载 WIFI 芯片,可直接连接无线网络. 准备 NOOBS 你可以购买预装有 NOOBS 的 SD 卡,或者从树莓派官网 下载 NOOBS.zip ...

  3. Maven进价:Maven构建系列文章

    Maven:基于Java平台的项目构建.依赖管理和项目信息管理. 1.构建 Maven标准化了构建过程 构建过程:编译.运行单元测试.生成文档.打包和部署 避免重复:设计.编码.文档.构建 2.依赖管 ...

  4. DDD:使用EntityFramework的话,如果只为聚合根设计仓储,其它实体如何处理?

    背景 DDD中只有聚合根可以有仓储,仓储负责整个聚合持久化的相关生命周期,在不使用工作单元或POCO的情况下,我们可以让Order内部直接调用DAL操作OrderItem.我们也可以让Order跟踪所 ...

  5. DDD:建模原语 之 四象图(转载的神文)

    “模型.状态和行为特征.场景”和“四象图”,建模观的命名与立象. 建模原语:四象图 作者:achieveidea@gmail.com 命名:模型.结构特征.行为特征.场景(及其规约). 释义:模型,描 ...

  6. Office Web Apps Server 概述

    Office Web Apps Server 是新的 Office 服务器产品,它提供 Word.PowerPoint.Excel 和 OneNote 的基于浏览器的版本.单个 Office Web ...

  7. 利用 word2vec 训练的字向量进行中文分词

    最近针对之前发表的一篇博文<Deep Learning 在中文分词和词性标注任务中的应用>中的算法做了一个实现,感觉效果还不错.本文主要是将我在程序实现过程中的一些数学细节整理出来,借此优 ...

  8. Android 学习笔记之SurfaceView的使用+如何实现视频播放...

    学习内容: 1.掌握Surface的使用... 2.Android中如何实现视频播放... 1.SurfaceView类的使用   在Android中,一般播放音频时我们可以去使用Android提供的 ...

  9. Python3.x中bytes类型和str类型深入分析

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分.文本总是Unicode,由str类型表示,二进制数据则由bytes类型表示.Python 3不会以任意隐式的方式混用str和b ...

  10. tips null和undefined的区别

    tips null和undefined的区别 1.undefined类型 undefined类型只有一个值,即特殊的undefined.在使用var声明变量但未对其加以初始化时,这个变量的值就是und ...