Java反射机制整理

Java反射

反射机制的概念

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

反射机制提供的功能

1、在运行时判断任意一个对象所属的类

2、在运行时构造任意一个类的对象

3、在运行时判断任意一个类所具有的成员变量和方法

4、在运行时调用任意任意一个对象的方法

5、生成动态代理

反射机制的作用

1、反编译:.class-->.java

2、通过反射机制访问java对象的属性、方法、构造方法等

提供的反射机制的类

1java.lang.class

2java.lang.reflect.Field

3java.lang.reflect.Constructor<T>

4java.lang.reflect.Method

5java.lang.reflect.Modifier

反射的方法、属性等操作可以查询API

点击反射API链接:

https://docs.oracle.com/javase/7/docs/api/java/lang/reflect/package-summary.html

首先看一个简单示例,通过一个对象获取完整的包名和类名:

package fanshe_test;
/**
 * 通过一个对象获得完整的包名和类名
 * @author fandi
 *
 */
public class Hello {
	public static void main(String[] args){
		Demo d = new Demo();
		System.out.println(d.getClass().getName());
	}
}
class Demo{
	
}

具体功能实现

反射机制获取类的三种方法

Class<?> demo1 = null;

//第一种方式(建议采用第一种方式)

demo1 = Class.forName("fanshe_test2.Demo");

//第二种方式:java中每个类型都有class属性

demo1 = Demo.class;

//第三种方式:java语言中任何一个java对象都有getClass方法,,这里的demo1是运行时类

demo1 = new Demo().getClass();

示例:

package fanshe_test2;
/**
 * 实例化Class类对象
 * @author fandi
 *
 */
public class Hello {
	public static void main(String[] args){
		Class<?> demo1 = null;
		Class<?> demo2 = null;
		Class<?> demo3 = null;
		try {
			//建议采用这种形式
			demo1 = Class.forName("fanshe_test2.Demo");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		demo2 = new Demo().getClass();
		demo3 = Demo.class;
		
		System.out.println("类名称" + demo1.getName());
		System.out.println("类名称" + demo2.getName());
		System.out.println("类名称" + demo3.getName());
	}
}
class Demo{
	
}

创建对象

    获取类后需要创建它的对象,使用newInstance

    demo.newInstance();//调用Demo的无参构造方法

示例:

package fanshe_test3;
/**
 * 通过Class实例化其他类的对象,通过无参构造实例化对象
 * @author fandi
 *
 */
public class Hello {
	public static void main(String[] args){
		Class<?> demo = null;
		try {
			demo = Class.forName("fanshe_test3.Person");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		Person per = null;
		try {
			per = (Person) demo.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		per.setAge(23);
		per.setName("张三");
		System.out.println(per);
		
	}
}
class Person{
	
	private String name;
	private int age;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "[name=" + this.name + ", age=" + this.age + "]";
	}
	
}

   注意:上面这个示例调用的无参构造函数,如果需要调用其它有参构造函数,则需要自己定义一个无参构造函数,否则会出现错误,学习下面的代码。

示例:

package fanshe_test4;

import java.lang.reflect.Constructor;

public class Hello {
	public static void main(String[] args){
		Class<?> demo = null;
		try {
			demo = Class.forName("fanshe_test4.Person");
		
		Person per1 = null;
		Person per2 = null;
		Person per3 = null;
		Person per4 = null;
		//取得全部的构造函数
		Constructor<?> con[] = demo.getConstructors();
		//判断所获取的构造函数的参数个数,以确定实例化的顺序
		for (int i = 0; i < con.length; i++) {
			System.out.print(con[i].getParameterCount() + " ");
		}
		System.out.println();
		//判断所获取的构造函数的参数类型,以确定实例化的顺序
		for (int j = 0; j < con.length; j++) {
			Class<?> clazzs[] = con[j].getParameterTypes();  
			System.out.print("con[" + j + "](");
			for (int k = 0; k < clazzs.length; k++) {
				if (k == clazzs.length-1) {
					System.out.print(clazzs[k].getName().toString());
				} else {
					System.out.print(clazzs[k].getName() + ",");
				}
			}
			System.out.println(")");
		}
		
		per1 = (Person) con[0].newInstance((Object)"李四",23);
		per2 = (Person) con[1].newInstance(24);
		per3 = (Person) con[2].newInstance((Object)"张三");
		per4 = (Person) con[3].newInstance();
	
//		try {
//			per1 = (Person) demo.newInstance();
//		} catch (InstantiationException e) {
//			e.printStackTrace();
//		} catch (IllegalAccessException e) {
//			e.printStackTrace();
//		}
		
		System.out.println(per1);
		System.out.println(per2);
		System.out.println(per3);
		System.out.println(per4);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
}
class Person {
		private String name;
		private int age;
		public Person(){
			
		}
		public Person(String name){
			this.name = name;
		}
		public Person(int age){
			this.age = age;
		}
		public Person(String name, int age) {
			super();
			this.name = name;
			this.age = age;
		}

		public String getName() {
			return name;
		}
		
		public int getAge() {
			return age;
		}

		public void setName(String name) {
			this.name = name;
		}
		public void setAge(int age) {
			this.age = age;
		}
		@Override
		public String toString() {
			return "[name=" + this.name + ", age=" + this.age + "]";
		}
}

运行结果:

2 1 1 0 
con[0](java.lang.String,int)
con[1](int)
con[2](java.lang.String)
con[3]()
[name=李四, age=23]
[name=null, age=24]
[name=张三, age=0]
[name=null, age=0]

获取属性

//获取所有成员属性

Field[] fs = demo.getDeclaredFields();

下面通过一个完整示例展示,示例:

package fanshe_test5;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
 * 获取所有接口、获取父类、获取其他类的所有构造函数、获取成员属性
 * @author fandi
 *
 */
public class Hello{
	public static void main(String[] args) {
		Class<?> demo = null;
		try {
			demo = Class.forName("fanshe_test5.Person");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//获取所有接口
		Class<?> inter[] = demo.getInterfaces();
		for (int i = 0; i < inter.length; i++) {
			System.out.println("实现的接口:" + inter[i].getName());
		}
		//获取父类
		Class<?> c = demo.getSuperclass();
		System.out.println("继承的父类:" + c.getName());
		//获取其他类的所有构造函数
		Constructor<?>[] cons = demo.getConstructors();
		for (int j = 0; j < cons.length; j++) {
			System.out.println("其他类的构造函数:" + cons[j].getName());
          System.out.println("其他类的构造函数:" + cons[j]);
		}
		//获取所有成员属性
		Field[] fs = demo.getDeclaredFields();
		//定义可变长的字符串,用来存储属性
		StringBuffer sb = new StringBuffer();
		//通过追加的方法,将每个属性拼接到此字符串中
		sb.append(Modifier.toString(demo.getModifiers()) + " class " + demo.getSimpleName() + "{\n");
		for (Field field : fs) {
			sb.append("\t");//空格
			sb.append(Modifier.toString(field.getModifiers()) + " ");//获得属性的修饰符
			sb.append(field.getType().getSimpleName() + " ");//获取属性类型的名字
			sb.append(field.getName() + ";\n");//属性的名字加回车
		}
		sb.append("}");
		System.out.println(sb);
	}
}
class Person implements China{
	private String sex = "女";
	public Person(){
		
	}
	public Person(String sex){
		this.sex = sex;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	@Override
	public void sayChina() {
		System.out.println("say China!!!");
	}

	@Override
	public void sayHello(String name, int age) {
		System.out.println("name:" + name + ", age:" + age);
	}
	
}
interface China{
	public static final String name = "张三";
	public static int age = 20;
	public void sayChina();
	public void sayHello(String name, int age);
}

获取方法

(详见Method.invoke方法一节的讲解)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值