Java反射基础内容---反射方式其他类获取构造方法并使用(Field,Method,Class.........方法介绍)

反射

什么是反射:反射是指在程序运行中分析类的一种能力。


通常代码运行过程:

源文件 字节码文件 运行
myc.javamyc.classobj.method()

 

 

 

 

 

反射的作用:

分析类:加载并初始化一个类,并且查看类中所有属性和方法

查看并使用:查看和使用类中的所有方法和属性

获取Class对象(字节码文件对象)的三种方式:

首先设定一个类,在另外的类中获取字节码对象,两个类实现获取

注意:一个源文件(.java文件)对应一个字节码文件对象(.class):意思就是说在一个类中无论获取多少个Class对象,最后所有的对象实现都是同一个功能:代码就是clazz1=clazz2

        //获取Class对象,在class_demo1中获取class_demo2字节码对象
            
		//Object类的getClass()方法;
		class_demo2 test1 = new class_demo2();
		Class clazz1 = test1.getClass();
		
		//方式二:类的静态属性
		Class clazz2 = class_demo2.class;
		
		//方式三:Class 类的静态方法
		Class clazz3 = Class.forName("class_demo2");

从A类来调用B类的构造方法:

Class类:

       成员方法:

                      public   Constructor    getConstructor(Class....params);    根据参数列表,获取对应的构造器对象(仅限公共构造函数)

                      public   Constructor    getDeclaredConstructor(Class....params); 根据参数列表,获取对应的构造器对象(包含私有构造函数)

                      public   Constructor    getConstructors(); 获取此类所有的构造函数(不包括私有构造)

Constructor类:构造器类

       成员方法:

                     public String getname();  获取构造函数名

                     public  T  newInstance(Object....params); 根据此构造函数和指定参数创建对象

案例演示:

目标:在Class_demo1 获取Class_demo2的方法

package csdn;

import java.lang.reflect.Constructor;

import csdn.*;

public class Class_demo1 {

	public static void main(String[] args) throws Exception {
		
		//获取Class_demo2类的字节码文件对象
		Class test1 = Class.forName("csdn.Class_demo2");
		//获取无参构造方法
		Constructor hq1 =test1.getConstructor();
		System.out.println(hq1);
		//获取有参构造方法
		Constructor hq2 =test1.getConstructor(String.class);
		System.out.println(hq2);
		//获取私有的有参构造
		Constructor hq3 =test1.getDeclaredConstructor(int.class);
		System.out.println(hq3);
		System.out.println("------------------------------------");
		//获取Class_demo2中的所有公共的构造函数
		Constructor [] hq4 =test1.getConstructors();
		for(Constructor test2: hq4) {
		System.out.println(test2);
		System.out.println("----------------------------------------");
		
		//以公共有参构造方法来介绍构造类对象
		
		//获取构造器名字,查看它那个类中的方法
		String name = hq2.getName();
		System.out.println(name);
		
		//根据构造器对象和参数,创建对应Class_demo2对象
		Object newInstance = hq2.newInstance("马六");
		Class_demo2 str = (Class_demo2) newInstance; //向下转型
		System.out.println(str);
		
		}
		
	}

}



--------------------------------------
输出结果:
public csdn.Class_demo2()
public csdn.Class_demo2(java.lang.String)
private csdn.Class_demo2(int)
------------------------------------
public csdn.Class_demo2()
----------------------------------------
csdn.Class_demo2
我叫马六
csdn.Class_demo2@31befd9f
public csdn.Class_demo2(java.lang.String)
----------------------------------------
csdn.Class_demo2
我叫马六
csdn.Class_demo2@1c20c684

从A类来调用B类的方法:

反射方式获取成员方法并使用:

Method对象:方法对象,属于Java.base模块,Java.lang.reflect包

通过Class对象来获取方法

                       getMethod(String name,Class<?>....parameterTypes): 返回Method对象,仅公共成员方法  【name;方法名,parameterTypes:方法的参数列表】

                       getDeclaredMethod(String,Class<?>....):返回一个method对象,可获取次优成员方法

                       getMethods();返回此类所有(不含私有)的方法数组

Method的常用方法:

                       String getName():返回方法名

                       Object invoke(Object obj,Object....args):在指定对象上调用方法参数为args

案例演示:

 

示例目标:通过上面的方法,来将Class_demo1类中调用Class_demo2中的方法

代码演示

package csdn;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import csdn.*;

public class Class_demo1 {

	public static void main(String[] args) throws Exception {
        //获取Class_demo2的字节码对象
		Class class1 = Class.forName("csdn.Class_demo2");
		//创建该类的构造器对象,然后创建出Class_demo2的对象
		Constructor con = class1.getConstructor();
		Class_demo2 de2 = (Class_demo2) con.newInstance();
		//通过获取demo2中的无参的公共方法,来进行调用
		Method me1 = class1.getMethod("test1");
		//获取方法的名字
		System.out.println(me1.getName());
		//调用此方法来进行输出
		me1.invoke(de2);
		
		Method me2 = class1.getMethod("test2", String.class);
		me2.invoke(de2, "在人间");
		
		Method me3 = class1.getDeclaredMethod("test3",int.class,int.class);
		//私有方法不能随便的调用,必须通过方法进行强制调用
		me3.setAccessible(true);
		int sum = (int)me3.invoke(de2, 1,2);
		System.out.println(sum);
		//通过调用数组的方法来对象类中所有的公共方法进行输出
		Method [] me4 =class1.getMethods();  //注意:因为在默认的情况的下Class_demo2是继承Object类的,所以将两个类中所有的功法方法进行输出
		for(Method me4test:me4) {
			System.out.println(me4test);
		}
		
		
		}
		
	}

输出结果:
test1
这是公共的无参方法
这是参数为在人间的构造方法
3
3
public void csdn.Class_demo2.test2(java.lang.String)
public void csdn.Class_demo2.test1()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) 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()

案例演示:通过反射方法获取方法并使用

注意:通过反射方法获取类的setter,并且使用该方法进行赋值

 

package csdn;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import csdn.*;

public class Class_demo1 {
		
		//获取Class_demo2的字节码对象
		Class test1 = Class.forName("csdn.Class_demo2");
		//创建该类的构造器对象,然后创建出Class_demo2的对象
		Constructor con = test1.getConstructor();
		Class_demo2 stu = (Class_demo2)con.newInstance();
		//获取指定的方法setName(),给对象设置值
		Method meth1 = test1.getMethod("setName",String.class);
		//调用此方法
		meth1.invoke(stu, "马先生");
		//打印
		System.out.println(stu);
		
		}
		
	}

Field讲解:

Class类:

           成员方法:

                           public Field getField(String name)  :返回一个Field对象,仅公共成员变量

                           public Field getField(String name)    :返回一个FIeld对象,可获取私有成员变量

                           public Field [] getDeclaredFields()      :返回此类方法所有(含私有)成员变量的数组

 

Field:属性类,用来表示所有的类(属性,成员变量)对象的。

         概述:属于Java.base 模块下的 Java.lang.reflect 包下的类

         成员方法:

                      public void  setAccessible(boolean flag):是否开启强制暴力反射(true:开启)

                      public void set(Object obj ,Object  value):设置obj对象的指定属性值

代码讲解:

package csdn;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;


import csdn.*;

public class Class_demo1 {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
           //获取Class_demo2的字节码对象
		Class test1 = Class.forName("csdn.Class_demo2");
		//创建该类的构造器对象,然后创建出Class_demo2的对象
		Constructor con = test1.getConstructor();
		Class_demo2 stu = (Class_demo2)con.newInstance();
		
		//一部解决创建构造对象,创建对象
		//Class_demo2 stu = (Class_demo2)test1.getConstructor().newInstance();
		
		//设置学生对象的的各个属性值
		Field f1 = test1.getDeclaredField("name");
		f1.set(stu, "马先生");
		//设置学生对象的的各个属性值
		Field f2 = test1.getDeclaredField("age");
		//开启暴力方法强制进行输出
		f2.setAccessible(true);
		f2.set(stu, 18);
		
		//打印Class_demo2的内容
		System.out.println(stu);
		
			}
			
		} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不想睡醒的梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值