新手学习java反射基础

一、反射

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

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。对于反射的操作实际上就是通过Class对象获取:

*a、java.lang.reflect.Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。操作类的成员变量。
*b、java.lang.reflect.Constructor<T>:操作类的够造函数。
*c、java.lang.reflect.Method:操作类的方法。

在学习反射基础前先创建一个Person对象作为实例

package com.jalja.org.base.relfect;

public class Person {

private String name;

int age;

public String address;

public Person() {

}

private Person(String name) {

this.name = name;

}

Person(String name, int age) {

this.name = name;

this.age = age;

}

public Person(String name, int age, String address) {

this.name = name;

this.age = age;

this.address = address;

}

public void show() {

System.out.println("show");

}

public void method(String s) {

System.out.println("method " + s);

}

public String getString(String s, int i) {

return s + "---" + i;

}

private void function() {

System.out.println("function");

}

@Override

public String toString() {

return "Person [name=" + name + ", age=" + age + ", address=" + address

+ "]";

}

}

二、获取类的Class对象

public static void getClassObject() throws ClassNotFoundException{

//方式一:Object的getClass()方法

Person person1=new Person();

Person person2=new Person();

Class c1=person1.getClass();

Class c2=person2.getClass();

System.out.println(person1==person2);//false

System.out.println(c1==c2);//true 不管JVM内存中有多少个对象,对于字节码文件来说只有一份

//方式二:数据类型的静态class属性

Class c3=Person.class;

System.out.println(c1==c3);//true

//方式三:Class 类的静态方法

//public static Class<?> forName(String className)throws ClassNotFoundException

Class c4=Class.forName("com.jalja.org.base.relfect.Person");

System.out.println(c1==c4);//true

}

三、java.lang.reflect.Constructor<T>:对象并使用Constructor类。

1、获取Constructor对象

//获取Class 对象所表示的类的构造方法

public static void getConstructorTest() throws Exception{

Class c4=Class.forName("com.jalja.org.base.relfect.Person");

//1、获取Class 对象所表示的类所有公共构造方法

//public Constructor<?>[] getConstructors() throws SecurityException

Constructor [] cs=c4.getConstructors();

//2、获取Class 对象所表示的类所有构造方法

//public Constructor<?>[] getDeclaredConstructors() throws SecurityException

Constructor[] cs2 =c4.getDeclaredConstructors();

//3、获取Class对象所表示类的指定指定公共构造方法, parameterTypes 参数是 Class 对象的一个数组 ,是指定数据类型的字节码

//public Constructor<T> getConstructor(Class<?>... parameterTypes);

Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象

//获取 该 构造函数 public Person(String name, int age, String address)

Constructor cs4=c4.getConstructor(String.class,int.class,String.class);

//4、获取Clss对象所表示类指定的构造范法官 parameterTypes 参数是 Class 对象的一个数组,它按声明顺序标识构造方法的形参类型的字节码。

//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);

//获取该构造 函数 private Person(String name) 的Constructor对象

Constructor cs5=c4.getDeclaredConstructor(String.class);

}

2、通过 Constructor 对象创建Class对象所表示类的实例

public static void createObject() throws Exception{

Class c4=Class.forName("com.jalja.org.base.relfect.Person");

//使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例

//public T newInstance(Object... initargs);

// Person person=new Person()

Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象

Object obj=cs3.newInstance();

//Person person=new Person("jalja", 21, "北京");

Constructor cs4=c4.getConstructor(String.class,int.class,String.class);

Object obj1=cs4.newInstance("jalja",21,"北京");

System.out.println(obj1);//Person [name=jalja, age=21, address=北京]

//实例化一个私有的构造函数 private Person(String name)

//控制java的访问检查

//public void setAccessible(boolean flag)

//将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。

//值为 false 则指示反射的对象应该实施 Java 语言访问检查。

Constructor cs5=c4.getDeclaredConstructor(String.class);

cs5.setAccessible(true);

Object obj2=cs5.newInstance("张三丰");

System.out.println(obj2);//Person [name=张三丰, age=0, address=null]

}

四、java.lang.reflect.Field

1、获取Field对象

//获取Class类的Field对象

public static void getFieldTest() throws Exception{

Class cs=Class.forName("com.jalja.org.base.relfect.Person");

//1、public Field[] getFields() throws SecurityException

//获取Class 对象所表示的类或接口的所有可访问公共(public修饰的)字段

Field [] fs=cs.getFields();

//2、public Field[] getDeclaredFields() throws SecurityException

// 获取Class 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段

Field [] fs1=cs.getDeclaredFields();

//3、public Field getField(String name)throws NoSuchFieldException, SecurityException;

//获取Class 对象所表示的类或接口的指定公共成员(public修饰)字段。name 参数是一个 String,用于指定所需字段的简称

Field fs2=cs.getField("address");

//public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException

//获取 Class 对象所表示的类或接口的指定已声明字段。name 参数是一个 String,它指定所需字段的简称

Field fs3=cs.getDeclaredField("name");

System.out.println(fs3);

}

2、通过Field对象对指定类属性赋值

//使用 Field对象

public static void createVarValue() throws Exception{

Class cs=Class.forName("com.jalja.org.base.relfect.Person");

Object obj=cs.getConstructor().newInstance();

Field addressField=cs.getField("address");

//public void set(Object obj, Object value);

//将指定对象变量上此 Field 对象表示的字段设置为指定的新值。如果底层字段的类型为基本类型,则对新值进行自动解包

//obj - 应该修改其字段的对象 value - 正被修改的 obj 的字段的新值

addressField.set(obj, "北京");

System.out.println(obj); //Person [name=null, age=0, address=北京]

//对非public修饰的变量操作

Field nameField=cs.getDeclaredField("name");

//控制java的访问检查

nameField.setAccessible(true);

nameField.set(obj, "张三丰");

System.out.println(obj);//Person [name=张三丰, age=0, address=北京]

}

五、java.lang.reflect.Method

1、获取Method对象

//获取Method对象

public static void getMethodTest() throws Exception{

Class cs=Class.forName("com.jalja.org.base.relfect.Person");

//1、public Method[] getMethods() throws SecurityException

//获取Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。

Method [] m1=cs.getMethods();

//2、public Method[] getDeclaredMethods() throws SecurityException

//获取Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法

Method [] m2=cs.getDeclaredMethods();

//3、public Method getMethod(String name, Class<?>... parameterTypes)throws NoSuchMethodException, SecurityException;

// 获取Class 对象所表示的类或接口的指定公共成员方法。name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组

Method m3=cs.getMethod("show");//无参的方法

Method m4=cs.getMethod("method",String.class);//带参的方法

//public Method getDeclaredMethod(String name, Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException

// Class 对象所表示的类或接口的指定已声明方法。name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组

Method m5=cs.getDeclaredMethod("function");//无参的方法

System.out.println(m5);

}

2、通过Method对象调用指定类的方法

// Method对象的使用

public static void createMethod() throws Exception{

Class cs=Class.forName("com.jalja.org.base.relfect.Person");

Object obj=cs.getConstructor().newInstance();

Method m3=cs.getMethod("show");//无参的方法

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

//对带有指定参数的指定对象调用由此 Method 对象表示的底层方法 obj - 从中调用底层方法的对象 args - 用于方法调用的参数

m3.invoke(obj);

//对带参方法的操作

Method m4=cs.getMethod("method",String.class);//带参的方法

m4.invoke(obj,"北京");

//对有返回值得方法操作

Method m6=cs.getMethod("getString",String.class,int.class);//带参的方法

Object str=m6.invoke(obj,"北京",200);

System.out.println(str);

//对私有无参方法的操作

Method m5=cs.getDeclaredMethod("function");

m5.setAccessible(true);

m5.invoke(obj);

}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 实例讲解Java基础之反射

    前期准备 编写一个真实类phone,实现list接口 public class Phone implements List { public double price; public String name; public Phone() { } public Phone(double price, String name) { this.price = price; this.name = name; } public double getPrice() { return price; } p

  • java基础之反射和泛型以及注解

     java基础之反射和泛型以及注解 泛型擦除 泛型擦除: 泛型只在编译时期有效,编译后的字节码文件中不存在泛型信息. 声明泛型集合,集合两端类型必须一致.类型也可以用包装类型,泛型的类型必须是引用类型,不能为基本类型. 实现公用的类和方法,对公用的业务进行抽取. 泛型方法/泛型类/泛型接口 public class GenericTest { /** * 泛型声明,定义泛型方法 * @param <T> * @param <K> * @param t * @param k */ p

  • Java 基础详解(泛型、集合、IO、反射)

    计划把 Java 基础的有些部分再次看一遍,巩固一下,下面以及以后就会分享自己再次学习的一点笔记!不是有关标题的所有知识点,只是自己觉得模糊的一些知识点. 1.对于泛型类而言,你若没有指明其类型,默认为Object: 2.在继承泛型类以及接口的时候可以指明泛型的类型,也可以不指明: 3.泛型也数据库中的应用: 写一个 DAO 类对数据库中的数据进行增删改查其类型声明为 <T> .每张表对应一个类,对应每一张表实现一个类继承该 DAO 类并指明 DAO 泛型为该数据表对应的类,再实现一个与该表匹

  • Java基础--反射机制

    反射 反射可以使我们很方便的创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代码链接.反射允许我们在编写和执行时,使我们的代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码. 反射机制作用 反编译:.class -> .java 通过反射机制访问Java对象的属性,方法,构造方法 反射的使用 反射机制获取类的三种方式 Class c1 = Class.forName("com.webb.basis.reflect.Demo"); // 一般采

  • 新手学习java反射基础

    一.反射 反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 要想解剖一个类,必须先要获取到该类的字节码文件对象.而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.对于反射的操作实际上就是通过Class对象获取: *a.java.lang.reflect.Field:提供有关类或接口的单个

  • 新手了解java 反射基础知识

    目录 一.反射概述 二.常用api 三.创建Class对象的四种方式 总结 一.反射概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意 对象的内部属性及方法. 加载完类之后,在堆内存的方法区中就产生了一个Class类型的对象 (一个类只有一个Class对象),这个对象就包含了完整的类的结构信 息.我们可以通过这个对象看到类的结构,这个对象就像一面镜子,透 过这个镜子看到类的结构,所以我们形象的

  • 新手学习Java对Redis简单操作

    REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统. Redis是一个开源的使用ANSI C语言编写.遵守BSD协议.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型. 代码如下 首

  • 新手了解java 集合基础知识(二)

    目录 三.Map 1.HashMap 2.TreeMap 3.ConcurrentHashMap 总结 三.Map ​ 存储的双列元素,Key是无序的,不可重复,而Value是无序,可重复的. 1.HashMap public class HashMapDemo { private Map map = null; public void init() { map = new HashMap(); map.put("a", "aaa"); map.put("

  • 新手了解java 集合基础知识(一)

    目录 一.概述 Java集合体系结构: 二.collection 1.List 1)ArrayList 2)LinkedList 2.set 1)HashSet 2)TreeSet 1.实体类 2.测试类: 3.实体类 4.测试类 总结 一.概述 集合是一种长度可变,存储数据的数据结构多样,存储对象多样的一种数据容器.Java中集合可分为:List集合.Set集合.HashMap集合,等. Java集合体系结构: 二.collection collection是Java中所有值存储集合的顶级接口

  • 新手了解java 多线程基础知识(二)

    目录 一.线程的生命周期 JDK中用Thread.State类定义了线程的几种状态: 二.线程同步 1.为什么要有线程同步 2.synchronized 2.1同步代码块 2.2同步方法 3.Lock锁 总结 一.线程的生命周期 JDK中用Thread.State类定义了线程的几种状态: 要想实现多线程,必须在主线程中创建新的线程对象.Java语言使用 Thread类及其子类的对象来表示线程,在它的一个完整的生命周期中通常 要经历如下的五种状态: 新建:当一个Thread类或其子类的对象被声明并

  • 新手了解java 多线程基础知识(一)

    目录 1.基本概念 2.多线程的创建 3.Thread类方法介绍 总结 1.基本概念 程序.进程.线程 程序(program)是为完成特定任务.用某种语言编写的一组指令的集 合.即指一段静态的代码,静态对象. 进程(process)是程序的一次执行过程,或是正在运行的一个程序.是 一个动态的过程:有它自身的产生.存在和消亡的过程--具有生命 周期.可以理解为一个正在运行的软件. 线程(thread),进程可进一步细化为线程,是一个程序内部的一条执行 路径.可以理解为一个软件的功能. 多线程程序的

  • 新手了解java IO基础知识(二)

    目录 一.IO概念 1.什么是输入 2.什么输出(Output) 二.流的分类 1.InputStream(字节流) 2.OutputStream(字节流) 3.Reader(字符流) 4.Writer(字符流) 三.总结(1+2) 1. File类及方法的使用 2.IO流的分类 3.IO流的四个基本类 总结 一.IO概念 I/O 即输入Input/ 输出Output的缩写,其实就是计算机调度把各个存储中(包括内存和外部存储)的数据写入写出 java中用"流(stream)"来抽象表示

  • 新手了解java IO基础知识(一)

    目录 一.File类 1.简介 2.创建方式 3.常用方法 总结 一.File类 1.简介 java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关 File 能新建.删除.重命名文件和目录,但 File 不能访问文件内容本 身.如果需要访问文件内容本身,则需要使用输入/输出流. 想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个 File对象. 2.创建方式 public File(String pathname);//以pathname为路径创建File对象,可

  • 新手了解java 异常处理基础知识

    目录 一.异常体系结构 1.什么是异常 2.异常的体系结构 二.异常处理 throw 与 throws 三.自定义异常 运行时异常 编译时异常 总结 一.异常体系结构 1.什么是异常 在java程序运行过程中,发生了一些意料之外的情况就是异常.在java中异常一颗分为两大类: (错误)Error 和 (异常)Exception. 对于(错误)Error来说,我们无法通过程序去解决所有的错误,仅仅可以去尝试捕获这些错误,但是无法处理,往往错误的发生对程序来说是重大的致命性问题,需要通过较大的调整去

随机推荐