Java反射代码示例

常用示例: 

package com.atguigu.java;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

import org.junit.Test;

public class TestReflection {
	//关于类的加载器:ClassLoader
	@Test
	public void test5() throws Exception{
		ClassLoader loader1 = ClassLoader.getSystemClassLoader();
		System.out.println(loader1);
		
		ClassLoader loader2 = loader1.getParent();
		System.out.println(loader2);
		
		ClassLoader loader3 = loader2.getParent();
		System.out.println(loader3);
		
		Class clazz1 = Person.class;
		ClassLoader loader4 = clazz1.getClassLoader();
		System.out.println(loader4);
		
		String className = "java.lang.String";
		Class clazz2 = Class.forName(className);
		ClassLoader loader5 = clazz2.getClassLoader();
		System.out.println(loader5);
		
		//掌握如下
		//法一:
		ClassLoader loader = this.getClass().getClassLoader();
		InputStream is = loader.getResourceAsStream("com\\atguigu\\java\\jdbc.properties");
		//法二:
//		FileInputStream is = new FileInputStream(new File("jdbc1.properties"));
		
		Properties pros = new Properties();
		pros.load(is);
		String name = pros.getProperty("user");
		System.out.println(name);
		
		String password = pros.getProperty("password");
		System.out.println(password);
		
	}
	//如何获取Class的实例(3种)
	@Test
	public void test4() throws ClassNotFoundException{
		//1.调用运行时类本身的.class属性
		Class clazz1 = Person.class;
		System.out.println(clazz1.getName());
		
		Class clazz2 = String.class;
		System.out.println(clazz2.getName());
		
		//2.通过运行时类的对象获取
		Person p = new Person();
		Class clazz3 = p.getClass();
		System.out.println(clazz3.getName());
		
		//3.通过Class的静态方法获取.通过此方式,体会一下,反射的动态性。
		String className = "com.atguigu.java.Person";
		
		
		Class clazz4 = Class.forName(className);
//		clazz4.newInstance();
		System.out.println(clazz4.getName());
		
		//4.(了解)通过类的加载器
		ClassLoader classLoader = this.getClass().getClassLoader();
		Class clazz5 = classLoader.loadClass(className);
		System.out.println(clazz5.getName());
		
		System.out.println(clazz1 == clazz3);//true
		System.out.println(clazz1 == clazz4);//true
		System.out.println(clazz1 == clazz5);//true
	}
	
	/*
	 * java.lang.Class:是反射的源头。
	 * 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的类加载器完成的)
	 * 此.class文件,此.class文件加载到内存以后,就是一个运行时类,存在在缓存区。那么这个运行时类本身就是一个Class的实例!
	 * 1.每一个运行时类只加载一次!
	 * 2.有了Class的实例以后,我们才可以进行如下的操作:
	 *     1)*创建对应的运行时类的对象
	 *     2)获取对应的运行时类的完整结构(属性、方法、构造器、内部类、父类、所在的包、异常、注解、...)
	 *     3)*调用对应的运行时类的指定的结构(属性、方法、构造器)
	 *     4)反射的应用:动态代理
	 */
	@Test
	public void test3(){
		Person p = new Person();
		Class clazz = p.getClass();//通过运行时类的对象,调用其getClass(),返回其运行时类。
		System.out.println(clazz);
	}
	
	
	//有了反射,可以通过反射创建一个类的对象,并调用其中的结构
	@Test
	public void test2() throws Exception{
		Class clazz = Person.class;
		
//		Class clazz1 = String.class;
		
		//1.创建clazz对应的运行时类Person类的对象
		Person p = (Person)clazz.newInstance();
		System.out.println(p);
		//2.通过反射调用运行时类的指定的属性
		//2.1
		Field f1 = clazz.getField("name");
		f1.set(p,"LiuDeHua");
		System.out.println(p);
		//2.2
		Field f2 = clazz.getDeclaredField("age");
		f2.setAccessible(true);
		f2.set(p, 20);
		System.out.println(p);
		
		//3.通过反射调用运行时类的指定的方法
		Method m1 = clazz.getMethod("show");
		m1.invoke(p);
		
		Method m2 = clazz.getMethod("display",String.class);
		m2.invoke(p,"CHN");
		
	}
	
	//在有反射以前,如何创建一个类的对象,并调用其中的方法、属性
	@Test
	public void test1(){
		Person p = new Person();
//		Person p1 = new Person();
		p.setAge(10);
		p.setName("TangWei");
		System.out.println(p);
		p.show();
//		p.display("HK");
	}
}

获取运行时类的 方法

package com.atguigu.java;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.junit.Test;

public class TestMethod {
	//1.获取运行时类的方法
	
	@Test
	public void test1(){
		Class clazz = Person.class;
		//1.getMethods():获取运行时类及其父类中所有的声明为public的方法
		Method[] m1 = clazz.getMethods();
		for(Method m : m1){
			System.out.println(m);
		}
		System.out.println();
		
		//2.getDeclaredMethods():获取运行时类本身声明的所有的方法
		Method[] m2 = clazz.getDeclaredMethods();
		for(Method m : m2){
			System.out.println(m);
		}
	}
	//注解 权限修饰符 返回值类型 方法名 形参列表 异常
	@Test
	public void test2(){
		Class clazz = Person.class;
		
		Method[] m2 = clazz.getDeclaredMethods();
		for(Method m : m2){
			//1.注解
			Annotation[] ann = m.getAnnotations();
			for(Annotation a : ann){
				System.out.println(a);
			}
			
			//2.权限修饰符
			String str = Modifier.toString(m.getModifiers());
			System.out.print(str + " ");
			//3.返回值类型
			Class returnType = m.getReturnType();
			System.out.print(returnType.getName() + " ");
			//4.方法名
			System.out.print(m.getName() + " ");
			
			//5.形参列表
			System.out.print("(");
			Class[] params = m.getParameterTypes();
			for(int i = 0;i < params.length;i++){
				System.out.print(params[i].getName() + " args-" + i + " ");
			}
			System.out.print(")");
			
			//6.异常类型
			Class[] exps = m.getExceptionTypes();
			if(exps.length != 0){
				System.out.print("throws ");
			}
			for(int i = 0;i < exps.length;i++){
				System.out.print(exps[i].getName() + " ");
			}
			System.out.println();
		}
	}
	//调用运行时类中指定的方法
	@Test
	public void test3() throws Exception{
		Class clazz = Person.class;
		//getMethod(String methodName,Class ... params):获取运行时类中声明为public的指定的方法
		Method m1 = clazz.getMethod("show");
		Person p = (Person)clazz.newInstance();
		//调用指定的方法:Object invoke(Object obj,Object ... obj)
		Object returnVal = m1.invoke(p);//我是一个人
		System.out.println(returnVal);//null
		
		Method m2 = clazz.getMethod("toString");
		Object returnVal1 = m2.invoke(p);
		System.out.println(returnVal1);//Person [name=null, age=0]
		//对于运行时类中静态方法的调用
		Method m3 = clazz.getMethod("info");
		m3.invoke(Person.class);
		
		//getDeclaredMethod(String methodName,Class ... params):获取运行时类中声明了的指定的方法
		Method m4 = clazz.getDeclaredMethod("display",String.class,Integer.class);
		m4.setAccessible(true);
		Object value = m4.invoke(p,"CHN",10);//我的国籍是:CHN
		System.out.println(value);//10
	}
}

获取对应的运行时类的 属性

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

import org.junit.Test;

public class TestField {
	//获取对应的运行时类的属性
	@Test
	public void test1(){
		Class clazz = Person.class;
		//1.getFields():只能获取到运行时类中及其父类中声明为public的属性
		Field[] fields = clazz.getFields();
		for(int i = 0;i < fields.length;i++){
			System.out.println(fields[i]);
		}
		System.out.println();
		//2.getDeclaredFields():获取运行时类本身声明的所有的属性
		Field[] fields1 = clazz.getDeclaredFields();
		for(Field f : fields1){
			System.out.println(f.getName());
		}
	}
	//权限修饰符  变量类型 变量名
	//获取属性的各个部分的内容
	@Test
	public void test2(){
		Class clazz = Person.class;
		Field[] fields1 = clazz.getDeclaredFields();
		for(Field f : fields1){
			//1.获取每个属性的权限修饰符
			int i = f.getModifiers();
			String str1 = Modifier.toString(i);
			System.out.print(str1 + " ");
			//2.获取属性的类型
			Class type = f.getType();
			System.out.print(type.getName() + " ");
			//3.获取属性名
			System.out.print(f.getName());
			
			System.out.println();
		}
	}
	
	//调用运行时类中指定的属性
	@Test
	public void test3() throws Exception{
		Class clazz = Person.class;
		//1.获取指定的属性
		//getField(String fieldName):获取运行时类中声明为public的指定属性名为fieldName的属性
		Field name = clazz.getField("name");
		//2.创建运行时类的对象 
		Person p = (Person)clazz.newInstance();
		System.out.println(p);
		//3.将运行时类的指定的属性赋值
		name.set(p,"Jerry");
		System.out.println(p);
		System.out.println("%"+name.get(p));
		
		System.out.println();
		//getDeclaredField(String fieldName):获取运行时类中指定的名为fieldName的属性
		Field age = clazz.getDeclaredField("age");
		//由于属性权限修饰符的限制,为了保证可以给属性赋值,需要在操作前使得此属性可被操作。
		age.setAccessible(true);
		age.set(p,10);
		System.out.println(p);
		
//		Field id = clazz.getField("id");
		
	}
	
}

获取

import java.lang.reflect.Constructor;

import org.junit.Test;

public class TestConstructor {
	@Test
	public void test1() throws Exception{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		//创建对应的运行时类的对象。使用newInstance(),实际上就是调用了运行时类的空参的构造器。
		//要想能够创建成功:①要求对应的运行时类要有空参的构造器。②构造器的权限修饰符的权限要足够。
		Object obj = clazz.newInstance();
		Person p = (Person)obj;
		System.out.println(p);
	}
	
	@Test
	public void test2() throws ClassNotFoundException{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		
		Constructor[] cons = clazz.getDeclaredConstructors();
		for(Constructor c : cons){
			System.out.println(c);
		}
	}
	
	//调用指定的构造器,创建运行时类的对象
	@Test
	public void test3() throws Exception{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		
		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
		cons.setAccessible(true);
		Person p = (Person)cons.newInstance("罗伟",20);
		System.out.println(p);
	}
}

构造器

import java.lang.reflect.Constructor;

import org.junit.Test;

public class TestConstructor {
	@Test
	public void test1() throws Exception{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		//创建对应的运行时类的对象。使用newInstance(),实际上就是调用了运行时类的空参的构造器。
		//要想能够创建成功:①要求对应的运行时类要有空参的构造器。②构造器的权限修饰符的权限要足够。
		Object obj = clazz.newInstance();
		Person p = (Person)obj;
		System.out.println(p);
	}
	
	@Test
	public void test2() throws ClassNotFoundException{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		
		Constructor[] cons = clazz.getDeclaredConstructors();
		for(Constructor c : cons){
			System.out.println(c);
		}
	}
	
	//调用指定的构造器,创建运行时类的对象
	@Test
	public void test3() throws Exception{
		String className = "com.atguigu.java.Person";
		Class clazz = Class.forName(className);
		
		Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
		cons.setAccessible(true);
		Person p = (Person)cons.newInstance("罗伟",20);
		System.out.println(p);
	}
}

获取其它的结构

import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.junit.Test;

public class TestOthers {
	//6.获取注解
	@Test
	public void test6(){
		Class clazz = Person.class;
		Annotation[] anns = clazz.getAnnotations();
		for(Annotation a : anns){
			System.out.println(a);
		}
	}
	
	//5.获取所在的包
	@Test
	public void test5(){
		Class clazz = Person.class;
		Package pack = clazz.getPackage();
		System.out.println(pack);
	}
	
	//4.获取实现的接口
	@Test
	public void test4(){
		Class clazz = Person.class;
		Class[] interfaces = clazz.getInterfaces();
		for(Class i : interfaces){
			System.out.println(i);
		}
	}
	
	//3*.获取父类的泛型
	@Test
	public void test3(){
		Class clazz = Person.class;
		Type type1 = clazz.getGenericSuperclass();
		
		ParameterizedType param = (ParameterizedType)type1;
		Type[] ars = param.getActualTypeArguments();
		
		System.out.println(((Class)ars[0]).getName());
	}
	
	//2.获取带泛型的父类
	@Test
	public void test2(){
		Class clazz = Person.class;
		Type type1 = clazz.getGenericSuperclass();
		System.out.println(type1);
	}
	
	//1.获取运行时类的父类
	@Test
	public void test1(){
		Class clazz = Person.class;
		Class superClass = clazz.getSuperclass();
		System.out.println(superClass);
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值