JAVA反射机制

反射的描述

  在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;

这种动态获取的信息以及动态调用对象的方法的功能就成为java语言的反射机制

 要想解剖一个类,必须先要获取到该类的字节码文件底线,而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件对于的Class类型的对象

 反射是框架设计的灵魂,

反射就是把java类中的各种成分映射成一个个的java对象

 

获取Class对象

1 Object ——> getClass();
2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
3 通过Class类的静态方法:forName(String  className)(常用)

public static void main(String[] args) {
	
	  Student stu =new Student();
	  Class stuclass =stu.getClass();
	  
	  System.out.println(stuclass.getName());
	  Class stuclass2 =Student.class;
	  System.out.println(stuclass == stuclass2);
	  
	  
	  
	  try {
		Class stuclass3 = Class.forName("com.shj.demo.Student");
		System.out.println(stuclass2 == stuclass3);
	  
	  } catch (ClassNotFoundException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

student

package com.shj.demo;

public class Student {

	public static void main(String[] args) {
		System.out.println("Student main");
	}
	public  String num;
	private int age;
	private String name;
	private char sex;
	//(默认的构造方法)	
	Student(String str){		
		System.out.println("(默认)的构造方法 s = " + str);
		}		
	//无参构造方法	
	public Student(){
		System.out.println("调用了公有、无参构造方法执行了。。。");
		}	
	//有一个参数的构造方法 
	public Student(char sex){
		System.out.println("性别:" + sex);
		}	
	//有多个参数的构造方法
	public Student(String name ,int age){	
		System.out.println("姓名:"+name+"年龄:"+ age);//这的执行效率有问题,以后解决。	
		}		
	//受保护的构造方法
	protected Student(boolean n){
	System.out.println("受保护的构造方法 n = " + n);	
	}	
	//私有构造方法	
	private Student(int age){
		System.out.println("私有的构造方法   年龄:"+ age);
		}
	


	private String getNameAndAge(String name ,int age) {
		return name+age;
	}
	
	public String getAgeString() {
		return "年龄"+age;
	}
	public void say(String str) {
		System.out.println(" say "+str);
	}

	@Override
	public String toString() {
		return "Student [age=" + age + ", name=" + name + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	
	
	
}

运行结果

 由此可以看出:  在运行期间, 一个类,只有一个class对象产生

三种方式常用第三种,第一种对象都有了还要反射干什么。第二种需要导入类的包,依赖太强,不导包就抛编译错误。

一般都使用第三种(例如:jdbc的时候加载驱动),一个字符串可以传入也可写在配置文件中等多种方法。

构造方法


	  try {
		  //加载class对象
		Class clazz=Class.forName("com.shj.demo.Student");
	System.out.println("所有的公共的构造方法");
		Constructor[] conArray =clazz.getConstructors();
		
		for (Constructor c : conArray) {
			System.out.println(c);
		}
		
		System.out.println("************所有的构造方法(包括:私有、受保护、默认、公有)***************");		
		conArray = clazz.getDeclaredConstructors();	
		for(Constructor c : conArray){	
			System.out.println(c);		
			}
		System.out.println("获取共有,无参的构造方法");
		Constructor pubcon =clazz.getConstructor(null);
		 System.out.println(pubcon);
		//调用构造方法
		Object stu =pubcon.newInstance();
		
		System.out.println("获取私有构造,并调用");

		Constructor	pricon =clazz.getDeclaredConstructor(char.class);
		System.out.println(pricon);
		//调用构造方法
		pricon.setAccessible(true);
		pricon.newInstance('M');
	  } catch (Exception e) {
		
		e.printStackTrace();
	}
	  
	  
  

运行结果

 

1.获取构造方法:

  1).批量的方法:public Constructor[] getConstructors():所有"公有的"构造方法

            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)

     

  2).获取单个的方法,并调用:public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;

  调用构造方法:

Constructor-->newInstance(Object... initargs)

2、newInstance是 Constructor类的方法(管理构造函数的类)

api的解释为:

newInstance(Object...initargs)

           使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

它的返回值是T类型,所以newInstance是创建了一个构造方法的声明类的新实例对象。并为之调用

 获取成员变量


	  //加载class对象
		try {
			Class clazz=Class.forName("com.shj.demo.Student");
		System.out.println("获取公共的字段");
		
		Field[] pubfie= clazz.getFields();
		for (Field field : pubfie) {
			System.out.println(field);
		}
		
		System.out.println("获取所有的字段");
		Field[] allfie= clazz.getDeclaredFields();
		for (Field field : allfie) {
			System.out.println(field);
		}
		System.out.println("调用共有的字段");
		Field field = clazz.getField("num");
		System.out.println(field);
		//生成一个对象
		Object obj =clazz.getConstructor().newInstance();
		field.set(obj, "12315");
		
		System.out.println("num "+ ((Student)obj).getNum());
		
		System.out.println("调用私有的字段");
		Field priField = clazz.getDeclaredField("name");
		System.out.println(priField);
		priField.setAccessible(true); //允许使用
		priField.set(obj, "张三");
		System.out.println(" name "+ ((Student)obj).getName());
		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	  
  

运行结果

 获取成员方法


		try {
			Class clazz=Class.forName("com.shj.demo.Student");
			System.out.println("获取公共的方法");
			
			Method [] pubMet= clazz.getMethods();
			for (Method method : pubMet) {
				System.out.println(method);
			}
			
			System.out.println("获取所有的方法");
			
			Method [] allMet= clazz.getDeclaredMethods();
			for (Method method : allMet) {
				System.out.println(method);
			}
			
			System.out.println("调用共有的方法");
			Method m1= clazz.getMethod("say", String.class);
			//实例化对象
			Object obj = clazz.getConstructor().newInstance();
			
			m1.invoke(obj, "hello ");
			
			
			System.out.println("调用私有的方法");
			Method m2= clazz.getDeclaredMethod("getNameAndAge", String.class,int.class);
			//实例化对象
			Object obj2 = clazz.getConstructor().newInstance();
			m2.setAccessible(true);
		Object result=	m2.invoke(obj, "JACK ", 20);
			System.out.println("返回值: -->"+ result);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	  
	  
  

运行结果

获取公共的方法
public boolean com.shj.demo.Student.equals(java.lang.Object)
public java.lang.String com.shj.demo.Student.toString()
public int com.shj.demo.Student.hashCode()
public java.lang.String com.shj.demo.Student.getName()
public void com.shj.demo.Student.setName(java.lang.String)
public java.lang.String com.shj.demo.Student.getNum()
public void com.shj.demo.Student.say(java.lang.String)
public java.lang.String com.shj.demo.Student.getAgeString()
public void com.shj.demo.Student.setSex(char)
public void com.shj.demo.Student.setNum(java.lang.String)
public char com.shj.demo.Student.getSex()
public void com.shj.demo.Student.setAge(int)
public int com.shj.demo.Student.getAge()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
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()
获取所有的方法
public boolean com.shj.demo.Student.equals(java.lang.Object)
public java.lang.String com.shj.demo.Student.toString()
public int com.shj.demo.Student.hashCode()
public java.lang.String com.shj.demo.Student.getName()
public void com.shj.demo.Student.setName(java.lang.String)
private java.lang.String com.shj.demo.Student.getNameAndAge(java.lang.String,int)
public java.lang.String com.shj.demo.Student.getNum()
public void com.shj.demo.Student.say(java.lang.String)
public java.lang.String com.shj.demo.Student.getAgeString()
public void com.shj.demo.Student.setSex(char)
public void com.shj.demo.Student.setNum(java.lang.String)
public char com.shj.demo.Student.getSex()
public void com.shj.demo.Student.setAge(int)
public int com.shj.demo.Student.getAge()
调用共有的方法
调用了公有、无参构造方法执行了。。。
 say hello 
调用私有的方法
调用了公有、无参构造方法执行了。。。
返回值: -->JACK 20

调用main方法


	  try {
		Class clazz=Class.forName("com.shj.demo.Student");
		Method main=clazz.getMethod("main", String[].class);
		//调用main方法
		//第一个参数为 对象类型,由于方法是static ,所以为nll即可 
		//第二个参数为 参数类型 
		main.invoke(null, (Object)new String[] {"a","b"});
	  
	  } catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
		
  

运行结果

Student main

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Hero_孙

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

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

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

打赏作者

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

抵扣说明:

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

余额充值