JAVA基础学习day27--反射机制

一、概述

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();
        }

    }
}
时间: 2024-10-20 08:05:30

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

Java Demo 学习 理解 反射机制 (基础学习)

目录 反射机制是什么 反射机制能做什么 反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ·获取一个对象的父类与实现的接口 ·获取某个类中的全部构造函数 - 详见下例 ·通过反射机制实例化一个类的对象 ·获取某个类的全部属性 ·获取某个类的全部方法 ·通过反射机制调用某个类的方法 ·通过反射机制操作某个类的属性 ·反射机制的动态代理 反射机制的应用实例 ·在泛型为Integer的ArrayList中存放一个String类型的对象. ·通过反射取得并修改数组的信息

Java基础学习总结——Java对象的序列化和反序列化

一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化. 把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中: 2) 在网络上传送对象的字节序列. 在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存.比如最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,于是Web容器就会把一些s

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

Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Oracle官方对反射的解释是 Reflection enables Java code to discover information about the fields, methods and constructors of loaded classes, and to use reflected fi

JAVA基础学习流程

JAVA基础学习: 第一步:学习JAVA的开发环境配置.开发第一个Java程序.也建议大家开始使用eclipse等IDE,不必纠结是不是一定要从记事本开始. 第二步:学习数据类型.运算符.变量.这是编程的基础,是程序的“砖块”.这些内容大多数编程语言都有,而且非常类似. 第三步:学习控制语句.这是编程的基础,是程序的“混凝土”.有了控制语句+变量,理论上你就可以写任意的程序了.因此,这是进入程序的门槛,需要大量的练习. 第四步:学习面向对象基础.通过类.对象.包等基本概念讲解.学习的时候,一定要

Java基础学习——数组初识(1)

Java基础学习--数组初识(1) 1什么是数组 Java中常见的一种数据结构就是数组,数组可以分为一维数组.二维数组和多维数组. 数组是由一组相同的变量组成的数据类型,数组中每个元素具有相同的数据类型,数组中的每个元素都可以用一个统一的数组名和下标来确定. 2 数组的使用 数组的一般使用步骤: 声明数组 分配内存给该数组 下面是一维数组为例: 数据类型  数组名 []: 数组名 = new 数据类型 [数据个数]: 2.1一维数组的声明与赋值 1.数组的声明 int  num [];    

JAVA基础学习笔记(2)

看了几天的视频了,都没时间来写下学习笔记,今天来写下第二次的学习笔记,前几天看的给忘记了,就写最新看到的吧 主要内容:1.类的变量与函数(方法) 2.对象的存储方式 3.新建一个对象及对象的赋值与调用 4.空对象 5.匿名对象 1.类的变量与函数(方法) class Dog      //类名 { String name;  //变量的声明 int age; String color; void bark()   //方法的定义(返回值为空,不带参数) { System.out.println(

Java基础学习--抽象类与抽象函数

Java基础学习--抽象类与抽象函数 abstract class 抽象类不能制造对象,但是可以定义变量,赋给这个变量的一定是他非抽象子类的对象: 抽象类中的抽象函数没有函数体,例如:public abstract void move(); 一个抽象类可以没有任何抽象方法,所有的方法都有方法体,但是整个类是抽象的. 抽象类中所有的的抽象函数必需子类的覆盖,而非抽象函数不需要覆盖.因为子类会继承父类的函数,如果不去覆盖继承来的抽象函数,那么子类就含有抽象函数,含有抽象函数的类必须要声明为抽象类.

JAVA基础学习笔记(1)

今天第一天开始学JAVA,时间:2014年6月17日 学习内容:1.java环境的架设 2.JAVA基本数据类型 1.JAVA环境的架设       1.要先去下载JDK,下载地址 2.安装完成后,设置环境变量 1.1环境变量的设置        1.右键-我的电脑-属性-高级-环境变量-系统变量,找到PATH,在里面加入jdk里bin目录的地址 如:c:\java\bin; 2.新建-名为classpath,值为. 1.2测试JAVA是否配置正确        1.在cmd里面输入javac.

java工厂类与反射机制

java 简单工厂类 2012-04-22 15:44:07|  分类: java |  标签:java工厂类  简单工厂类  |举报|字号 订阅 简单工厂模式需要由以下角色组成: 接口                        接口的实现类(简单工厂模式里面的具体产品角色)                        工厂注意对比以下三个实例的不同实例1: package org.jzkangta.factorydemo01;//定义接口interface Car{    public