Java反射reflect学习笔记_3:反射类的方法

原创 2015年11月17日 16:15:24

今天给大家po出我的第三份关于学习反射的笔记,关于对类的方法的反射。其中包括静态方法,普通方法,带参数的方法,以及最重要的String[]数组的方法的反射以及需要注意的细节问题,都是基础,所以请各位多多包涵!

有关前面两篇文章请看下面:

Java反射reflect学习笔记_1:反射的简述

Java反射reflect学习笔记_2:反射类的构造函数



//===================================================

// 反射类的方法

//===================================================

本文由机智猫亲手写,转载请尊重版权:http://blog.csdn.net/nthack5730/article/details/49888833


首先,通过Class获取类的字节码

|Class clazz = Class.forName("com.marer.reflect.Person");

|

1.反射无参的方法: public void aa1()

|Method method = clazz.getMethod("aa", null);

|第一个参数:方法名;第二个参数:方法的参数,若为无参方法可以为null值

|

|执行方法:

|method.invoke(p, null);//第一个参数:你要调用哪个对象的方法,假设new了一个新的对象p;第二个参数:被反射的对象的方法所需要的参数,如果无参数则传null

|

|

|

2.反射带一个或者多个参数的方法: public void aa(String name, int age)

|Method method = clazz.getMethod("aa", String.class, int.class);//第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用

|第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用

|

|执行方法:

|method.invoke(p, "老张,成功了", 23);//第一个参数:你要调用哪个对象的方法,假设new了一个新的对象p;第二个参数:可变参数

|

|

|

3.反射带数组的方法,并返回Class数组: public Class[] aa(String name, int[] ages)

|Method method = clazz.getMethod("aa", String.class, int[].class);//在这里,原方法第二个参数中是个int数组,那么就传int[].class

|

|执行方法:

|Class cs[] = (Class[]) method.invoke(p, "老李,成功了", new int[]{1,2,3});

|

|

|

4.反射类的私有方法: private void aa(InputStream in)

|Method method = clazz.getDeclaredMethod("aa", InputStream.class);//private方法用getDeclaredMethod()

|method.setAccessible(true);//打开访问权限,暴力反射

|

|执行方法:

|Class cs[] = (Class[]) method.invoke(p, new FileInputStream("D:\\我的文档\\Q.txt"));

|

|

|

5.反射类的静态方法: public static void aa(int num)

|Method method = clazz.getMethod("aa", int.class);

|

|执行方法:

|method.invoke(123);//静态方法调用不需要对象,直接执行

|与普通方法不同,在静态方法中,因为静态方法是一直存在的,因此不需要通过对象的访问进行调用,只需要直接调用

|而需要通过对象调用的普通方法,执行的是对象内部的方法,对其他的对象没有影响

|

|

|

6.反射类的main方法,以及有且只有一个参数并且参数类型为数组的方法的反射、特殊的参数String[] 的反射方法: 

|public static void main(String[] args)

|public static boolean doDelete(int[] ids)

|

|反射:

|Method method = clazz.getMethod("main", String[].class);//这里指定方法名为main,指定参数为String[]数组

|

|执行方法一:

|method.invoke(null, new Object[]{new String[]{"123","weq"}});//第一种方法,将String[]数组参数包装在数组中,到了invoke()里面就会对应拆分出一个String数组

|

|执行方法二:

|method.invoke(null, (Object) new String[]{"123","weq"});//第二种方法,推荐使用,将参数的数组包装在一个Object中,并且由JDK拆分,拆分出第一个参数就是数组,那么就会通过调用

|//注意:这里将String[]数组参数封装为(Object)对象是允许的因为Object对象是所有对象的始祖

|

|

|注意:1.上面的main方法的反射以及调用,适用所有的有且只有一个String[]数组为参数的方法,对于其他类型的数组可以不用包装,例如只有一个int[]参数的方法

|method.invoke(null, new int[]{1,2});//如果只有一个int[]数组为参数的反射,可以不用像上面那样封装,即使封了也没问题invoke(null, (Object)new int[]{1,2})

|

|

|注意:2.对于String和包装类(例如:Integer,Charater..),如果一个或多个参数都是同样的(String或包装类),就可以通过new 数组的形式进行invoke反射调用,例如:

|1.一个或多个String参数,必须都是String,如果有一个参数不一样(例如String和String[]数组都是不一样的,那么就不能够通过下面的方法进行反射调用方法

|类方法:public static void test(String s1, String s2)

|反射方法:Method method = clazz.getMethod("test", String.class, String.class);

|反射方法的invoke调用:method.invoke(null, new String[]{"asd","123"});

|//当然,上面的也可以通过普通的两个个字符串参数进行invoke调用

|

|

|

|2.一个或多个包装类的方法都是一样的:(Integer,Character...)

|类方法:public static void test6(Integer a1, Integer a2)

|反射方法:Method method = clazz.getMethod("test6", Integer.class,Integer.class);

|反射方法的invoke调用:method.invoke(null, new Integer[]{1,2});

|//必须注意:两个基础数据类型的int不能通过数组进行invoke反射调用,乖乖地一个个传参吧

|//Method method = clazz.getMethod("test4", int.class,int.class);

|//method.invoke(null, 1,2);

|

|3.但是对于两个或以上的String[]数组声明的方法就不可以用一个数组进行invoke调用

|类方法:public static void test8(String[] s1, String[] s2)

|反射方法:Method method = clazz.getMethod("test8", String[].class, String[].class);

|反射方法的invoke调用:method.invoke(null, new String[]{"abc","def"});//这时候是抛出参数要求长度不一的异常的

|//运行结果是抛异常的,因此证明是不能通过这种方法去进行invoke调用

|

|

|4.普通类也不能通过数组的方式进行invoke调用

|类方法:public static void test7(Person p1, Person p2)

|反射方法:Method method = clazz.getMethod("test7", Person.class,Person.class);

|反射方法的invoke调用:method.invoke(null, new Person(),new Person());//两个非String或非包装类就不能用数组来invoke反射调用

|

|本文由机智猫亲手写,转载请尊重版权:http://blog.csdn.net/nthack5730/article/details/49888833

|

|总结:通过上述几个样例,大家应该可以看到反射方法的invoke调用的不同的形式

|        其实只要注意有且只有一个String[]数组作为参数的方法的反射以及调用注意的问题就可以了【直接将String[]数组的参数强转成Object即可】

|除了多个String参数或多个包装类型的方法(都必须都是String类型的参数或包装类型)可以通过在invoke的时候传一个String[]数组参数以外

|其他方法都是必须按照参数的要求对号入座

|PS.一般情况为了避免造成不必要的麻烦,都建议按照参数的个数要求进行对号入座

|



本文由机智猫亲手写,转载请尊重版权:http://blog.csdn.net/nthack5730/article/details/49888833



关于之前写的Person类:

package com.marer.reflect;

import java.io.InputStream;
import java.util.List;

public class Person {
	public String str = "aa";
	int a = 1233;
	private int num = 4564564;
	private static int num2 = 9527;
	private int nums;
	private String name;
	
	
	public Person(){
		System.out.println("person");
	}
	
	public Person(String name){
		System.out.println("person name:" + name);
	}
	
	public Person(String name, int age){
		System.out.println("person name:" + name + "\tage:" + age);
	}
	
	private Person(List list){
		System.out.println("list");
	}
	
	
	//方法
	
	public void aa(){
		System.out.println("aa");
	}
	
	public void aa(String name, int age){
		System.out.println("person name:" + name + "\tage:" + age);
	}
	
	public Class[] aa(String name, int[] ages){
		System.out.println("有返回值的");
		return new Class[]{String.class};
	}
	
	private void aa(InputStream in){
		System.out.println(in);
	}
	
	public static void aa(int num){
		System.out.println(num);
	}
	
	
	public static void main(String[] args){
		System.out.println("main方法运行");
	}
	
	
	public static void test(String[] args){
		System.out.println("字符串数组参数方法调用成功");
	}
	
	public static void test(String s1, String s2){
		System.out.println("两个字符串");
		System.out.println(s1);
		System.out.println(s2);
	}
	
	public static void test_1(String s1, String s2,String s3){
		System.out.println("三个字符串");
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);
	}
	
	public static void test2(int[] a1, int[] a2){
		System.out.println("两个参数为数组的方法");
		System.out.println(a1.length);
		for(int a: a1){
			System.out.print(a+",");
		}
		System.out.println("\n"+a2.length);
		for(int a: a2){
			System.out.print(a+",");
		}
	}
	
	public static void test3(int[] a1, int a2){
		System.out.println("第一个参数为数组,第二个参数为普通类型的方法");
		System.out.println(a1.length);
		for(int a: a1){
			System.out.print(a+",");
		}
		System.out.println(a2);
	}
	
	
	public static void test4(int a1, int a2){
		System.out.println("两个参数为普通类型int,用数组进行invoke");
		System.out.println(a1);
		System.out.println(a2);
	}
	
	public static void test5(int[] a1){
		System.out.println("int 数组");
		for(int a:a1){
			System.out.println(a);
		}
	}
	
	public static void test6(Integer a1, Integer a2){
		System.out.println("两个参数为普通类型Integer,用数组进行invoke");
		System.out.println(a1);
		System.out.println(a2);
	}
	
	public static void test7(Person p1, Person p2){
		System.out.println("两个参数为普通类型Integer,用数组进行invoke");
		System.out.println(p1);
		System.out.println(p2);
	}
	
	
	public static void test8(String[] s1, String[] s2){
		System.out.println("两个字符串数组");
		System.out.println(s1.toString());
		System.out.println(s2.toString());
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public static int getNum2() {
		return num2;
	}

	public static void setNum2(int num2) {
		Person.num2 = num2;
	}

	public int getNums() {
		return nums;
	}

	public void setNums(int nums) {
		this.nums = nums;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}


本文由机智猫亲手写,转载请尊重版权:http://blog.csdn.net/nthack5730/article/details/49888833

这次本文的Demo类:

package com.marer.reflect;

import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;

import org.junit.Test;

//反射类的方法
public class Demo3 {
	
	//反射类的方法:public void aa1()
	@Test
	public void test1() throws Exception{
		
		Person p = new Person();
		
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("aa", null);//第一个参数:方法名;第二个参数:方法参数
		
		method.invoke(p, null);//第一个参数:你要调用哪个对象的方法;第二个参数:被反射的对象的方法所需要的参数
		
	}
	
	
	
	//反射类的方法:public void aa(String name, int age)
	@Test
	public void test2() throws Exception{
		
		Person p = new Person();
		
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("aa", String.class, int.class);//第一个参数:方法名;第二个参数:可变参数,根据你所需要调用方法的约定进行调用
		
		method.invoke(p, "老张,成功了", 23);//第一个参数:你要调用哪个对象的方法;第二个参数:可变参数
		
	}
	
	
	//反射类的方法:public Class[] aa(String name, int[] ages)
	@Test
	public void test3() throws Exception{
		
		Person p = new Person();
		
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("aa", String.class, int[].class);//在这里,原方法第二个参数中是个int数组,那么就传int[].class
		
		Class cs[] = (Class[]) method.invoke(p, "老李,成功了", new int[]{1,2,3});
		
		System.out.println(cs[0]);
	}
	
	
	
	//反射类的私有方法:private void aa(InputStream in)
	@Test
	public void test4() throws Exception{
		
		Person p = new Person();
		
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getDeclaredMethod("aa", InputStream.class);//private方法用getDeclaredMethod()
		
		method.setAccessible(true);//打开访问权限,暴力反射
		
		Class cs[] = (Class[]) method.invoke(p, new FileInputStream("D:\\我的文档\\Q.txt"));
	}
	
	
	
	//反射类的静态方法:public static void aa(int num)
	@Test
	public void test5() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("aa", int.class);
		method.invoke(123);//静态方法调用不需要对象
	}
	
	
	
	//反射类的方法:public static void main(String[] args)
	@Test
	public void test6() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("main", String[].class);//这里指定方法名为main,指定参数为String[]数组
		
//		method.invoke(null, new Object[]{new String[]{"123","weq"}});//第一种方法,将String[]数组参数包装在数组中,到了invoke()里面就会对应拆分出一个String数组
		method.invoke(null, (Object) new String[]{"123","weq"});//第二种方法,推荐使用,将参数的数组包装在一个Object中,并且由JDK拆分,拆分出第一个参数就是数组,那么就会通过调用
		
		//main方法的反射获取和调用
	}
	
	
	
	//反射类方法:public static void test(String[] args)
	@Test
	public void test7() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test", String[].class);
		
		method.invoke(null, (Object) new String[]{"asd","123"});
		
	}
	
	
	//反射类方法:public static void test(String s1, String s2)
	@Test
	public void test8() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test", String.class, String.class);

		method.invoke(null, new String[]{"asd","123"});
		
	}
	
	
	//反射类方法:public static void test_1(String s1, String s2, String s3)
	@Test
	public void test8_1() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test_1", String.class, String.class,String.class);

		method.invoke(null, new String[]{"asd","123","456"});
		
	}
	
	
	//反射类方法:public static void test2(int[] a1, int[] a2)
	@Test
	public void test9() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test2", int[].class,int[].class);
		
		method.invoke(null, new int[]{1,2,3},new int[]{4,5,6});
	}
	
	
	//反射类方法:public static void test3(int[] a1, int a2)
	@Test
	public void test10() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test3", int[].class,int.class);
		
		method.invoke(null, new int[]{1,2,3},4);
	}
	
	
	//反射类方法:public static void test4(int a1, int a2)
	@Test
	public void test11() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test4", int.class,int.class);
		
		method.invoke(null, 1,2);//两个基础数据类型的int不能通过数组进行invoke反射调用,乖乖地一个个传参吧
	}
	
	
	//反射类方法:public static void test5(int[] a1)
	@Test
	public void test12() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test5", int[].class);
		
		method.invoke(null, new int[]{1,2});
	}
	
	
	//反射类方法:public static void test6(Integer a1, Integer a2)
	@Test
	public void test13() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test6", Integer.class,Integer.class);
		
		method.invoke(null, new Integer[]{1,2});//两个基础数据类型的int不能通过数组进行invoke反射调用
	}
	
	
	
	//反射类方法:public static void test7(Person p1, Person p2)
	@Test
	public void test14() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test7", Person.class,Person.class);
		
		method.invoke(null, new Person(),new Person());//两个非String或非包装类就不能用数组来invoke反射调用
	}
	
	
	//反射类方法:public static void test8(String[] s1, String[] s2)
	@Test
	public void test15() throws Exception{
		Class clazz = Class.forName("com.marer.reflect.Person");
		Method method = clazz.getMethod("test8", String[].class, String[].class);
		method.invoke(null, new String[]{"abc","def"});//运行结果是抛异常的
	}
	
}





版权声明:本文为博主原创文章,未经博主允许不得转载。更多请关注:http://blog.csdn.net/nthack5730

黑马程序员--Java基础加强学习笔记之Class类、反射(Reflect)

一、反射的基础Class类 1、如何得到各个字节码对应的实例对象 (1)类名.class,例如 System.class (2)对象.getClass(),例如 new Data().getClass...

Java反射reflect学习笔记_2:反射类的构造函数

反射类的构造函数, 首先,通过Class获取类的字节码: Class clazz = Class.forName("com.marer.reflect.Per...

Java学习笔记-反射(reflect)

1.反射概念:通过对象获取类的信息。(正常是加载类信息到内存创建对象) Class:也是一个类,描述类的类,所有类的共性。   2.类的对象(字节码)的获取方法: (1)Object类的getClas...

Java学习笔记23 反射机制(reflect…

1.         反射机制(reflection)的功能是在运行时环境中,动态获取类的信息以及动态调用对象的方法。 2.         Java语言反射机制提供的功能 1)    在运行...
  • ltlf_21
  • ltlf_21
  • 2017年05月05日 15:05
  • 92

java反射学习笔记(3)----使用反射来调用方法

我们在类中调用方法的时候,一般都是,先实例化一个具体的对象,然后用这个对象来调用具体的函数方法,而我们说的利用反射来调用方法,是用函数方法对象来调用具体的对象。 1、getMethod(“方法名”,参...

java反射学习笔记(3)---使用Class来获取方法、成员变量、构造函数信息

1、基本知识点获取方法信息: 基本数据类型,void关键字都存在类类型 class.getMethods()方法获取是该类的所有public方法,包括从父类继承的方法; class.getDec...

浅谈Java反射(Reflect)技术--常用方法

Java反射(Reflect)技术 概念:动态获取在当前Java虚拟机中的类、接口或者对象等等信息(运行过程中读取内容) 1.作用(面试问题): 1.1 解除两个类之间的耦合性,即在未得...

JAVA学习之反射(1):Class类和java.lang.reflect包的使用

一,能够分析类能力的程序称为“反射”,反射库(java.lang.reflect)提供了精心设计的工具集,以便编写能够动态操作Java代码的程序。 二,在程序运行期间,java运行时系统始终为所有的对...

JAVA反射系列之Field,java.lang.reflect.Field使用获取方法。

java.lang.reflect.Field使用 Field. 首先必须明一点 Field类主要是用来辅助获取和操作类的属性的! 1.怎么通过反射获取类的属性      先来看JDK提供的方法有如下...

Java--Reflect(反射)专题5——方法反射的基本操作

转载请注明:http://blog.csdn.net/uniquewonderq 1.如何获取某个方法 方法的名称和方法的参数列表才能唯一决定某个方法 2.方法的反射操作 method...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java反射reflect学习笔记_3:反射类的方法
举报原因:
原因补充:

(最多只允许输入30个字)