Java基础21-反射

原创 2012年04月29日 17:15:23

1.反射构造函数Constructor

package cn.base25.reflect;

import cn.base25.reflect.domain.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import org.junit.Test;

public class ReflectConstructor {

	/*
	 * 反射构造函数
	 * 		注: 1.使用getConstructor,只能反射public的构造方法
	 * 			2.使用getDeclaredConstructor,可以反射所有的构造函数
	 */
	@Test
	@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
	public void test1() {
		
		try {
			//1-1.根据类名取得Class对象(Person.class),会将Persona.class加载进来
			Class clazz = Class.forName("cn.base25.reflect.domain.Person");
			
			/*			
			//创建Class对象的实例
			Person p = (Person) clazz.newInstance(); 				//注意: person类必须得有无参的构造函数,所以我们应该先反射其构造函数
			*/
			
			//1-2.反射构造函数,取到无参的构造函数
			Constructor constructor = clazz.getConstructor();		//根据实际构造函数是否有参数,来获取对应的构造函数
			
			//1-3.由Constructor对象,来创建Person对象
			Person p = (Person) constructor.newInstance();
			
			constructor = clazz.getConstructor(int.class);			//注意: 是int.class,千万别写成: Integer.class
			p = (Person) constructor.newInstance(20);
			
			//2.暴力反射private的构造函数
			constructor = clazz.getDeclaredConstructor(String.class, int.class);  	//使用的是: getDeclaredConstructor
			constructor.setAccessible(true);										//设为true,取消java语言访问检查
			p = (Person) constructor.newInstance("rose", 18);
			
			//3-1.列出Person类的所有构造函数(包括private)
			Constructor[] cons = clazz.getDeclaredConstructors();
			for(Constructor c : cons) {
				System.out.println(c.toString());
			}
			
			//3-2.使用getConstructor,只能反射public的构造方法
			System.out.println();
			Constructor[] cons2 = clazz.getConstructors();
			for(Constructor c : cons2) {
				System.out.println(c.toString());
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException ex) {
			ex.printStackTrace();
		} catch (IllegalAccessException ex) {
			ex.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}

 

2.反射方法Method

package cn.base25.reflect;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

import cn.base25.reflect.domain.Person;

public class ReflectMethod {

	/*
	 * 反射方法:
	 * 		注意: 1.clazz.getMethod(String name, Object...obj)--只会得到具体某一个方法,而不是同名的所有方法!!
	 * 			  2.使用getMethod,可以反射父类的方法!!!!!
	 */			  
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Test
	public void test1() {
		try {
			//0.加载Person类
			Class clazz = Class.forName("cn.base25.reflect.domain.Person");
			
			//1-1.使用getDeclaredMethod反射所有方法
			Method[] methods = clazz.getDeclaredMethods();		//使用getDeclaredMethod,会将Person类自身的所有方法列出(不包括父类的方法)
			for(Method m : methods) {
				System.out.println(m.toGenericString());
			}
			System.out.println();
			
			//1-2.使用getMethod反射所有方法
			methods = clazz.getMethods();						//使用getMethod,会将所有public的方法列出(包括父类继承而来的)
			for(Method m : methods) {
				System.out.println(m.toGenericString());
			}
			System.out.println();
			
			//2-1.取得一个无参的Person对象
			Person p = (Person) clazz.newInstance();
			
			//2-2.通过反射,调用方法
			Method m1 = clazz.getMethod("study");					//取得具体方法名的无参的method对象		
			//2-3.调用无参的study方法
			m1.invoke(p); 											//invoke方法的调用需要: 对象和实际参数
																	//这边也可以写成: m1.invoke(p, null)			
			//3-1.取得带一个int参数的"study"方法对象
			Method m2 = clazz.getMethod("study", int.class);    		
			//3-2.调用带int参数的study方法
			m2.invoke(p, 20);
			
			//4.反射private的方法--使用getDeclaredMethod,并setAccessible(true)
			Method m3 = clazz.getDeclaredMethod("study", int.class, String.class);
			m3.setAccessible(true);
			m3.invoke(p, 20, "sun");
			
			//5.反射静态方法
			Method m4 = clazz.getMethod("study", String.class);
			m4.invoke(p, "sta");									//这边也可写成: m4.invoke(null, "sta");
			
			//6.反射main主函数
			Method m5 = clazz.getMethod("main", String[].class);	//注意: String[].class
			m5.invoke(null, (Object)new String[]{"test"});			//这边也可以写成: m5.invoke(null, new Object[]{new String[]{"test2"}});
			
			//7.反射Object的方法										//注意: 根据上面可以反射父类的方法知,可以反射那些方法
			Method m6 = clazz.getMethod("hashCode");
			System.out.println(m6.invoke(p));
			
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e2) {
			e2.printStackTrace();
		} catch (NoSuchMethodException e2) {
			e2.printStackTrace();
		} catch (IllegalArgumentException e3) {
			e3.printStackTrace();
		} catch (IllegalAccessException e3) {
			e3.printStackTrace();
		} catch (InvocationTargetException e3) {
			e3.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

3.反射字段Field

package cn.base25.reflect;

import java.lang.reflect.Field;

import org.junit.Test;

import cn.base25.reflect.domain.Student;

public class ReflectField {

	/*
	 * 反射字段:
	 * 		注意: 1.使用getDeclaredFields,只会列出Student自身的字段(而不包括Person的),不能反射Person的字段!!!
	 * 			 2.一个Method/Field对象,对应一个具体方法/一个具体字段,但同时可以对应多个类对象的这一个方法/字段!!!
	 * 			3.判断出字段的类型!!!!
	 */
	@SuppressWarnings({ "rawtypes" })
	@Test
	public void test1() {
		
		try {
			//1.加载Student类
			Class clazz = Class.forName("cn.base25.reflect.domain.Student");
			
			//2-1.使用getDeclaredFileds,反射出所有的字段		//使用getDeclaredFields,只会列出Student自身的字段(而不包括Person的)
			Field[] fields = clazz.getDeclaredFields();
			for(Field f : fields) {
				System.out.println(f.toGenericString());
			}
			System.out.println();
					
			//2-2.使用getFileds,反射出所有的字段
			Field[] fields2 = clazz.getFields();			//使用getMethods,只会列出public的Student字段
			for(Field f : fields2) {
				System.out.println(f.toGenericString());
			}
			
			//3.创建一个Student对象
			Student stu = (Student) clazz.newInstance();
			
			//4.设置public的"sName"字段的值,并取出,查看结果
			Field field = clazz.getField("sName");
			field.set(stu, "李四");
			System.out.println(field.get(stu)); 			//打印stu对象的sName的值
			
			//5.反射private的"name3"字段
			Field field2 = clazz.getDeclaredField("name3");	//1.需要使用getDeclaredField
			field2.setAccessible(true);						//2.还要打开权限
			field2.set(stu, "王伟");
			System.out.println(field2.get(stu));
			
			//6.取得"name3"字段的类型,判断出其类型
			Class cType = field2.getType();
			if(String.class.equals(cType)) {
				String s  = (String) field2.get(stu);
				System.out.println("\"name3\"字段的类型是 " + s.getClass() +", 值为:" + s);
			}
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
	}
}


附:

1.Person类:

package cn.base25.reflect.domain;

@SuppressWarnings("unused")
public class Person {
	public String name="张三";
	public int age;
	
	//构造函数
	public Person() {
		System.out.println("person()");
	}
	
	public Person(int id) {
		System.out.println("public person(int)");
	}
	
	private Person(String name, int id) {
		System.out.println("private person(String, int)");
	}
	
	Person(int id, int j, int m) {
		System.out.println("public person(int)");
	}
	
	protected Person(int id, int j) {
		System.out.println("public person(int)");
	}
	
	//方法
	public void study() {
		System.out.println("public study()");
	}	
	
	void study(int i, int j, String s) {
		System.out.println("默认 study(int i, int j, String s)");
	}
	
	public void study(int i) {
		System.out.println("public study(int i)");
	}	
	
	protected void study(int i, int j) {
		System.out.println("protected study(int i, int j)");
	}
	
	private void study(int i ,String s) {
		System.out.println("private study(int i ,String s)");
	}
	
	public static void study(String s) {
		System.out.println("public static study(String s)");
	}
	
	public static void main(String []args) {
		System.out.println("reflect main() sucessful!");		
	}
}

 

2.Student类:

package cn.base25.reflect.domain;

@SuppressWarnings("unused")
public class Student {
	public String sName;
	String name1;
	protected String name2;
	private String name3;
	public int age;
	public static int id;
	
	//构造函数
	public Student() {
		System.out.println("person()");
	}
	
	public Student(int id) {
		System.out.println("public person(int)");
	}
	
	private Student(String name, int id) {
		System.out.println("private person(String, int)");
	}
	
	Student(int id, int j, int m) {
		System.out.println("public person(int)");
	}
	
	protected Student(int id, int j) {
		System.out.println("public person(int)");
	}
	
	//方法
	public void study() {
		System.out.println("public study()");
	}	
	
	void study(int i, int j, String s) {
		System.out.println("default study(int i, int j, String s)");
	}
	
	public void study(int i) {
		System.out.println("public study(int i)");
	}	
	
	protected void study(int i, int j) {
		System.out.println("protected study(int i, int j)");
	}
	
	private void study(int i ,String s) {
		System.out.println("private study(int i ,String s)");
	}
	
	public static void study(String s) {
		System.out.println("public static study(String s)");
	}
	
	public static void main(String []args) {
		System.out.println("reflect main() sucessful!");		
	}
}

java反射和注解开发(备java基础,javaee框架原理)

Java注解是附加在代码中的一些元信息,用于一些工具在编译、运行时进行解析和使用,起到说明、配置的功能。 注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用。 qq群:362969068
  • 2016年10月18日 09:40

Java反射基础机制简介

一、什么是反射?Java反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称...
  • duan1078774504
  • duan1078774504
  • 2016-07-02 07:55:16
  • 2074

深入解析Java反射(1) - 基础

一、回顾:什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性。 Oracle官方对反射的...
  • Zero_shan
  • Zero_shan
  • 2017-07-10 16:58:08
  • 197

JavaSE基础之反射

->理解 Class 类 ->理解 Java 的类加载机制 ->学会使用 ClassLoader 进行类加载 ->理解反射的机制 ->掌握 Constructor、Method、Field 类的用法 ...
  • yuchao2015
  • yuchao2015
  • 2017-04-17 21:04:41
  • 323

【框架基础】:Java反射机制详解(一)

在学习框架设计之前,先来了解一下框架基础——Java反射机制。         一、什么是反射机制         反射机制是在程序运行状态时,对于任意一个类,都能够知道这个类的所有属性和方法;对...
  • erlian1992
  • erlian1992
  • 2016-11-29 15:13:05
  • 1778

框架的基础——反射

在慕课网上学完了相关 反射的课程,先对自己所学的内容做一个总结。    1.Class类       1.1 在面向对象的世界里,万事万物皆对象,但java语言中,静态的成员,普通的数据类型不是对...
  • sinat_34311901
  • sinat_34311901
  • 2016-07-13 14:42:34
  • 249

Java反射获取基本类型、包装类型、String对象类型的字段值

package com.zkn.reflect.classinfo; import java.lang.reflect.Field; import java.lang.reflect.Type; im...
  • zknxx
  • zknxx
  • 2015-05-28 13:14:16
  • 12688

Java进阶之reflection(反射机制)——反射概念与基础

这里写链接内容  反射机制是Java动态性之一,而说到动态性首先得了解动态语言。那么何为动态语言?一、动态语言动态语言,是指程序在运行时可以改变其结构:新的函数可以引进,已有的函数可以被删除等结构上的...
  • xu__cg
  • xu__cg
  • 2016-10-20 22:00:53
  • 5976

Android框架常用java基础知识:反射,注解,动态代理

Android框架常用java基础知识:反射,注解,动态代理 在学习Android的框架的源码的时候,发现大部分框架中都是有对java机制的灵活应用。常见的反射,代理,动态代理,注解...
  • qyl10241024
  • qyl10241024
  • 2015-10-30 21:40:14
  • 922

Java 反射基础(上)

本文主要介绍 Java 反射机制。Java 反射机制在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。...
  • My_TrueLove
  • My_TrueLove
  • 2016-05-02 20:48:45
  • 2743
收藏助手
不良信息举报
您举报文章:Java基础21-反射
举报原因:
原因补充:

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