java中的反射

一.什么是反射,反射有什么用

  以前我们创建对象有几种方式?只有一种方式去new一个对象。有的时候在程序的开发阶段,你并不知道要创建哪
个类的对象,或者你不知道要调用类的哪个方法,或者访问类的哪个属性。在程序的运行阶段,你才知道要创建哪
个类的对象。那怎么解决这种问题?
研究一下spring的核心的源码的业务逻辑,分以下几个步骤
  1,读取applicationContext.xml,获取所有的bean标签的class属性
  2,获取bean标签的class属性之后,class属性的值在java程序中应该以什么数据类型来存储,用字符串类型来存储
  3,根据class属性的字符串描述符来创建一个这个描述符描述的对象。需求到这一步,就变成:
  根据一个字符串,来创建一个字符串描述的对象。
使用反射必须先获取类的Class对象,每个类在java的虚拟机中,默认都会存在一个class的对象。如果要使用反
射,必须先获取这个Class对象。
二.class对象的使用
  1.Class对象获取的三种方式
创建Person.java
package com.aaa.spring.entity;
/**
* 人员类
*/
public class Person {
}
/**
* Class对象获取的三种方式
*/
public class Test02 {
public static void main(String[] args) throws Exception {
//获取Person的Class对象
//第一种方式,通过Class.forName()
Class clazz1 = Class.forName("com.aaa.spring.entity.Person");
System.out.println(clazz1);
//第二种方式 访问类的class对象
Class clazz2 = Person.class;
System.out.println(clazz2);
//第三种方式,通过对象的getClass方法
Person person = new Person();
Class clazz3 = person.getClass();
System.out.println(clazz3);
}
}

  2.利用Class对象获取构造方法

创建Person2.java

package com.aaa.spring.entity;
public class Person2 {
//默认无参的构造
public Person2(){}
//公共的有一个参数的方法
public Person2(String name){}
//私有的有两个参数的方法
private Person2(String name,int age){}
}
/**
* 利用CLass对象获取构造方法
*/
public class Test03 {
public static void main(String[] args) throws Exception {
//获取类的Class对象
Class clazz = Person2.class;
//获取类的所有公共的构造方法
Constructor[] constructors = clazz.getConstructors();
for (Constructor con :
constructors) {
System.out.println(con);
}
System.out.println("===");
//获取类的所有的声明的构造方法
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor con :
declaredConstructors ) {
System.out.println(con);
}
//根据参数获取指定的构造方法
System.out.println("获取指定一个参数的公共的构造方法:");
Constructor con1 = clazz.getConstructor(String.class);
System.out.println(con1);
System.out.println("获取两个参数的私有的构造方法:");
Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(con2);
}
}

  3.利用Class对象获取类的方法

创建Person3.java

package com.aaa.spring.entity;
public class Person3 {
public void info(){
System.out.println("我是一个无参的公共方法");
}
public void info(String name,int age){
System.out.println("我是一个有两个参数的额公共方法");
}
private void info(String name){
System.out.println("我是一个有一个参数的私有的方法");
}
}
/**
* 利用Class对象获取方法
*/
public class Test04 {
public static void main(String[] args) throws Exception {
//获取类的Class对象
Class clazz = Person3.class;
Method[] methods = clazz.getMethods();
System.out.println("获取类的所有的公共的方法,包含父类的方法:");
for (Method method:
methods) {
System.out.println(method);
}
System.out.println("获取所有的声明的方法:");
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method method:
declaredMethods) {
System.out.println(method);
}
System.out.println("获取两个参数的公共的方法:");
Method method = clazz.getMethod("info",String.class,int.class);
System.out.println(method);
System.out.println("获取一个参数的私有的方法:");
Method method2 = clazz.getDeclaredMethod("info",String.class);
System.out.println(method2);
}
}

  4.利用Class对象获取类的属性

创建Person4.java

package com.aaa.spring.entity;
public class Person4 extends Person{
public String name;
private int age;
}
public class Test05 {
public static void main(String[] args) throws
Exception{
//获取类的Class对象
Class clazz = Person4.class;
System.out.println("获取类的所有公共的属性(也包括父类中的公共的属性):");
Field[] fields = clazz.getFields();
for (Field field :
fields) {
System.out.println(field);
}
System.out.println("获取类的所有声明的属性:");
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field:
declaredFields ) {
System.out.println(field);
}
//获取公共的name属性
System.out.println("获取公共的name属性");
Field name = clazz.getField("name");
System.out.println(name);
System.out.println("获取私有的age属性:");
Field age = clazz.getDeclaredField("age");
System.out.println(age);
}
}

  5.利用Class对象创建类的实例

创建Person5.java

package com.aaa.spring.entity;
public class Person5 {
private String name;
//默认无参的构造
public Person5(){}
//公共的有一个参数的方法
public Person5(String name){
this.name=name;
}
//私有的有两个参数的方法
private Person5(String name,int age){}
public void info(){
System.out.println(name);
}
}
/**
* 利用CLass对象创建类的实例
*/
public class Test06 {
public static void main(String[] args) throws Exception {
//获取类的class对象
Class clazz = Class.forName("com.aaa.spring.entity.Person5");
//创建类的对象有两种方式
//第一种,调用Class对象的newInstance方法,该方法会会调用类的默认的无参的构造
Person5 person51 =(Person5) clazz.newInstance();
System.out.println(person51);
//第二种,根据类的构造方法对象创建类的实例
Constructor constructor = clazz.getConstructor(String.class);
Person5 person52 = (Person5)constructor.newInstance("zhangsan");
System.out.println(person52);
person52.info();
Constructor con2 = clazz.getDeclaredConstructor(String.class, int.class);
//设置忽略构造方法的访问级别
con2.setAccessible(true);
Person5 person53 = (Person5)con2.newInstance("zhangsan", 18);
person53.info();
}
}

  6.利用Class对象调用类的方法

创建Person6.java

package com.aaa.spring.entity;
public class Person6 {
public void info(){
System.out.println("我是一个无参的公共方法");
}
public void info(String name,int age){
System.out.println("我是一个有两个参数的额公共方法");
}
private void info(String name){
System.out.println("我是一个有一个参数的私有的方法");
}
}
/**
* 利用Class对象访问类的方法
*/
public class Test07 {
public static void main(String[] args) throws Exception {
Person6 p6 = new Person6();
p6.info();
p6.info("zhangsan",12);
//获取类的Class对象
Class clazz = Class.forName("com.aaa.spring.entity.Person6");
//利用反射创建对象
Object p61 = clazz.newInstance();
//获取info()方法
Method info = clazz.getMethod("info");
//调用用法
info.invoke(p61);
//获取info(string,int)这个方法
Method info1 = clazz.getMethod("info", String.class, int.class);
//调用方法
info1.invoke(p61,"张三",16);
//利用反射调用类的私有的方法
Method info2 = clazz.getDeclaredMethod("info",String.class);
//忽略方法的访问级别
info2.setAccessible(true);
//调用方法
info2.invoke(p61,"李四");
}
}

  7.利用Class对象返回类的属性

创建Person7.java

package com.aaa.spring.entity;
public class Person7 {
public String name="zhangsan";
private int age=12;
}
/**
* 利用Class对象访问类的属性
*/
public class Test08 {
public static void main(String[] args) throws Exception {
Person7 p = new Person7();
String name = p.name;
System.out.println(name);
p.name="lisi";
System.out.println(p.name);
//获取类的CLass对象
Class clazz = Class.forName("com.aaa.spring.entity.Person7");
//获取对象的属性值,打印出来
//创建对象
Object p1 = clazz.newInstance();
//获取类的属性的对象
Field f1 = clazz.getField("name");
//设置属性的值
f1.set(p1,"lisi");
//获取属性的值
Object name1 = f1.get(p1);
System.out.println(name1.toString());
Field f2 = clazz.getDeclaredField("age");
//忽略访问级别
f2.setAccessible(true);
System.out.println(f2.get(p1));
}
}

 

posted on 2019-05-23 19:15  不酷也要写代码  阅读(224)  评论(0编辑  收藏  举报

导航