Java中的反射

参考链接:

Java 反射 -超详细讲解(附源码)_皮卡卡西的博客-CSDN博客_反射java

反射 + 暴力反射 - Liang-shi - 博客园

java.lang.reflect.Field.getAnnotation()方法示例 -java.lang.reflect包教程™

文章一 

反射
概述:
反射不需要程序员自己实现,都是底层框架或者JVM去使用的一个技术.
专门用来解析  .class文件里 的所有数据 (公开的,私有的)
2,原理
把解析 到的 .class里的数据 封装成了Class工具类
3怎么获取Class对象
Class对象是 封装了.class文件里的数据 ,,可以通过Class对象提供的种方法解析数据
static Class<?> forName(String className)  
类名.class
对象.getClass()

反射
测试获取Class对象

public class C1 {
public static void main(String[] args) throws ClassNotFoundException {
        method();//获取Class对象
    }
    //获取Class对象--用来解析.class文件里的所有数据
    public static void method() throws ClassNotFoundException {
        //参数是类的全路径 -- 包名.类名
        Class c = Class.forName("java.lang.String");
        Class c2 = String.class;
        Class c3 = new String().getClass();
        System.out.println(c);
        System.out.println(c2);
        System.out.println(c3);
    }
}
反射Student类里的所有信息
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class C1_Student {
    public static void main(String[] args) throws Exception {
        //1,获取Student类的Class对象
        Class s = Student.class;
        //method(s);//解析 构造方法
        //method2(s);//解析 成员变量
        //method3(s);//解析 成员方法
        //method4(s);//用反射 创建对象
        //method5(s);//用反射 设置变量的值
        method6(s);//用反射 执行方法
    }
    //用反射 执行方法
    public static void method6(Class s) throws Exception {
        //获取指定的方法 public void test(int a)
        Method m = s.getMethod("test", int.class);
        Object o = s.newInstance();
        //invoke(m,n)--m是对象--n是要给方法传入的参
        m.invoke(o,50);//执行方法
    }
    //用反射 设置变量的值
    public static void method5(Class s) throws Exception {
        //TODO  public String name ;
        Field f = s.getField("name");

        Object o = s.newInstance();
        //set(m,n)--m是对象--n是想要设置啥值
        f.set(o,"jack");//设置值
        System.out.println( f.get(o) );//获取值
    }
    //用反射 创建对象
    public static void method4(Class s) throws Exception{
        //用反射new --自动调用无参构造
        Object o = s.newInstance();
        Student s2 = (Student) o ;//向下转型,目的是使用子类的特有功能
        s2.show();//使用了Student类里功能
    }
    //解析Student.class文件中的 成员方法
    //getMethods() getMethod() -- 获取自己和父类的所有  公开的方法
    public static void method3(Class s) throws NoSuchMethodException {
        //获取 所有方法
        Method[] ms = s.getMethods();
        //遍历数组,获取每个方法m
        for (Method m : ms) {
            System.out.println( m.getName() );//获取方法名
            Class[] c = m.getParameterTypes();//获取参数类型
            System.out.println( Arrays.toString(c) );
        }
        //TODO 获取 特定的方法 public void test(int a)
        Method m = s.getMethod("test", int.class);
        System.out.println( m.getName() );
    }




    //解析Student.class文件中的 成员变量
    //getFields() getField() --获取公开的
    public static void method2(Class s) throws Exception {
        //获取所有 成员变量们~~~~
        Field[] fs = s.getFields();
        //遍历,得到每个成员变量f
        for (Field f : fs){
            //获取变量名
            System.out.println(f.getName());
            //获取变量类型
            System.out.println(f.getType().getName());
        }
        //根据属性名获取属性
        Field f = s.getField("name");
        //获取属性类型
        System.out.println(f.getType().getName());

    }
    //解析Student.class文件中的构造方法
    //getConstructors() getConstructor()--获取公开的
    public static void method(Class s) throws NoSuchMethodException {
        //获取 所有的构造方法 存入Constructor[]
        Constructor[] cs = s.getConstructors();
        //遍历数组,得到每个构造方法c
        for (Constructor c: cs
             ) {
            //获取构造方法的 名称
            System.out.println(c.getName());
            //TODO 解析构造方法的 参数的类型
            Class[] cc =c.getParameterTypes();
            System.out.println(cc);
        }
        //TODO 获取指定的构造方法 --public Student(int age)
        //getConstructor()的参数是 构造方法的参数类型 的Class对象
        Constructor con = s.getConstructor(int.class);
        System.out.println(con.getName()+"--");
    }


}

暴力反射
--1,概述
专门用来 反射 类中的 公开数据 和 私有数据
--2,新的API
--普通反射 -- 只能获取public的
getMethod()
getMethods()
getField()
getFields()
getConstructor()
getConstructors()
--暴力反射 --除了public的甚至连private都可以获取
getDeclaredMethod()
getDeclaredMethods()
getDeclaredField()
getDeclaredFields()
getDeclaredConstructor()
getDeclaredConstructors()
--创建Person类
public class Person {
    private String name;
    int age;
    public char sex;

    private void show(){
        System.out.println("show..");
    }
    void test(int a){
        System.out.println("test.."+a);
    }
}

--创建测试类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test3_Person {
    public static void main(String[] args) throws Exception {
        //        method();//暴力反射 成员变量
        method2();//暴力反射 成员方法
    }
    //TODO 暴力反射成员方法
    public static void method2() throws Exception {
        Class c = Person.class;
        //暴力反射--获取所有方法
        Method[] ms = c.getDeclaredMethods();
        //遍历数组,获取每个方法m
        for (Method m : ms) {
            //获取方法名
            System.out.println(m.getName());
        }
        //TODO 获取指定的方法
        Method m = c.getDeclaredMethod("show");
        Object oo = c.newInstance();

        m.setAccessible(true);//开启 私有资源的 访问权限
        m.invoke(oo);
    }
    //TODO 暴力反射成员变量
    public static void method() throws Exception {
        Class c = Person.class;
        //暴力反射--获取所有属性,包括 public的private的default的
        Field[] fs = c.getDeclaredFields();
        //遍历数组,得到每个属性f
        for (Field f : fs) {
            //获取属性名
            System.out.println( f.getName() );
        }

        //只获取一个私有的属性
        Field f = c.getDeclaredField("name");
        Object o = c.newInstance();

        //对私有的属性操作抛出异常:IllegalAccessException
        f.setAccessible(true);//开启私有的访问权限
        f.set(o,"jack");//设置值
        System.out.println( f.get(o) );//获取值
    }
}
反射和暴力反射的区别

总结:
1, 普通反射 和 暴力反射 的区别 ?
  暴力反射是可以获取public的甚至private
  普通反射只能获取public的

2, 怎么使用暴力反射?
  用对API ( getDeclaredXxx() )
  设置访问权限( setAccessible(true) )

3, getDeclaredXxx() 和 getXxx() 的区别??
  getXxx() 获取public资源 -- 获取自己的方法和父类的方法
  getDeclaredXxx() 获取所有资源 --只获取自己的方法

文章2

Java 反射 -超详细讲解(附源码)_皮卡卡西的博客-CSDN博客_反射java

1:反射概述


  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
  实际上,我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象。这个实例对象称之为类对象,也就是Class对象。那么,Class对象又是什么对象呢?

2:Class对象特点


  下图是Class类的api(图片来自于Java基础之—反射(非常重要)_敬业小码哥的博客-CSDN博客_反射

在这里插入图片描述
   从图中可以得出以下几点:

  •  Class 类的实例对象表示正在运行的 Java 应用程序中的类和接口。也就是jvm中有很多的实例,每个类都有唯一的Class对象。
  • Class 类没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机自动构造的。也就是说我们不需要创建,JVM已经帮我们创建了。
  • Class 对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法

3:反射的使用

  假设我们现在有一个Hero类

package pojo;
public class Hero {
	public String name; //姓名
    public float hp; //血量
    public float armor; //护甲
    public int moveSpeed; //移动速度
}

1:获取类对象

获取类对象有3种方式

  1. Class.forName()(常用)
  2. Hero.class
  3. new Hero().getClass()

在一个JVM中,一种类,只会有一个类对象存在。所以以上三种方式取出来的类对象,都是一样。(此处准确是在ClassLoader下,只有一个类对象)
示例:

package pojo;
public class ObjectTest {
	
	public static void main(String[] args) {
        String className = "pogo.Hero";
		try {
        	//获取类对象的第一种方式
            Class pClass1 = Class.forName(className);
            //获取类对象的第二种方式
            Class pClass2 = Hero.class;
            //获取类对象的第三种方式
            Class pClass3 = new Hero().getClass();
            System.out.println(pClass1==pClass2);//输出true
            System.out.println(pClass1==pClass3);//输出true
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 }
}

  三种方式中,常用第一种,第二种需要导入类的包,依赖太强,不导包就抛编译错误。第三种对象都有了还要反射干什么。一般都第一种,一个字符串可以传入也可写在配置文件中等多种方法。

2 利用反射机制创建对象


基本步骤
  与传统的通过new 来获取对象的方式不同反射机制,反射会先拿到Hero的“类对象”,然后通过类对象获取“构造器对象”再通过构造器对象创建一个对象,具体步骤:

1.获取类对象 Class class = Class.forName("pojo.Hero");
2.获取构造器对象 Constructor con = clazz.getConstructor(形参.class);
3 获取对象 Hero hero =con.newInstance(实参);

上面是最简单的获取方法,当Hero的构造方法不是无参构造方法时,获取构造器对象略有不同,见下面测试:

构造方法不同时,获取构造器对象的方法

示例:

Hero类添加6种构造方法
 

//---------------构造方法-------------------
	//(默认的构造方法)
	Hero(String str){
		System.out.println("(默认)的构造方法 s = " + str);
	}
	
	//无参构造方法
	public Hero(){
		System.out.println("调用了公有、无参构造方法执行了。。。");
	}
	
	//有一个参数的构造方法
	public Hero(char name){
		System.out.println("姓名:" + name);
	}
	
	//有多个参数的构造方法
	public Hero(String name ,float hp){
		System.out.println("姓名:"+name+"血量:"+ hp);
	}
	
	//受保护的构造方法
	protected Hero(boolean n){
		System.out.println("受保护的构造方法 n = " + n);
	}
	
	//私有构造方法
	private Hero(float hp){
		System.out.println("私有的构造方法   血量:"+ hp);
	}
  1. 通过反射机制获取对象
package test;
public class ConstructorTest {
	
	 
	/*
	 * 通过Class对象可以获取某个类中的:构造方法、成员变量、成员方法;并访问成员;
	 * 
	 * 1.获取构造方法:
	 * 		1).批量的方法:
	 * 			public Constructor[] getConstructors():所有"公有的"构造方法
	            public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
	     
	 * 		2).获取单个的方法,并调用:
	 * 			public Constructor getConstructor(Class... parameterTypes):获取单个的"公有的"构造方法:
	 * 			public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
	 * 		
	 * 2.创建对象
	 * 		Constructor对象调用newInstance(Object... initargs)
	 */

	 
	public static void main(String[] args) throws Exception {
		//1.加载Class对象
		Class clazz = Class.forName("pojo.Hero");
		
		
		//2.获取所有公有构造方法
		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 con = clazz.getConstructor(null);
		//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型
		//2>、返回的是描述这个无参构造函数的类对象。
		System.out.println("con = " + con);
		//调用构造方法
		Object obj = con.newInstance();
		
		
		System.out.println("******************获取私有构造方法,并调用*******************************");
		con = clazz.getDeclaredConstructor(float.class);
		System.out.println(con);
		//调用构造方法
		con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
		obj = con.newInstance(100);
	}
	

}

输出:

**********************所有公有构造方法*********************************
public pojo.Hero(java.lang.String,float)
public pojo.Hero(char)
public pojo.Hero()
************所有的构造方法(包括:私有、受保护、默认、公有)***************
private pojo.Hero(float)
protected pojo.Hero(boolean)
public pojo.Hero(java.lang.String,float)
public pojo.Hero(char)
public pojo.Hero()
pojo.Hero(java.lang.String)
*****************获取公有、无参的构造方法*******************************
con = public pojo.Hero()
调用了公有、无参构造方法执行了。。。
******************获取私有构造方法,并调用*******************************
private pojo.Hero(float)
私有的构造方法   血量:100.0

总结:

1.获取构造器对象方法:
  1).批量的方法:
public Constructor[] getConstructors():所有"公有的"构造方法
public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
  2).获取单个的方法:
public Constructor getConstructor(Class… parameterTypes): 获取单个的"公有的"构造方法
public Constructor getDeclaredConstructor(Class…parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有;
 

3: 获取成员变量并使用

基本步骤

1.获取HeroPlus类的对象 new方法/第2章中的方法 h
2. 获取属性 Field f1 = h.getDeclaredField("属性名")
3. 修改属性 f1.set(h,实参)注意这里的h是对象,不是类对象

示例:

  1. 新增HeroPlus类
package pojo;
public class HeroPlus {
	public String name;
    public float hp;
    public int damage;
    public int id;
     
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public HeroPlus(){
         
    }
    public HeroPlus(String string) {
        name =string;
    }
 
    @Override
    public String toString() {
        return "Hero [name=" + name + "]";
    }
    public boolean isDead() {
        // TODO Auto-generated method stub
        return false;
    }
    public void attackHero(HeroPlus h2) {
        System.out.println(this.name+ " 正在攻击 " + h2.getName());
    }
}
  1. 获取属性并修改
    package test;
    public class ParaTest {
    	 public static void main(String[] args) {
             HeroPlus h =new HeroPlus();
             //使用传统方式修改name的值为garen
             h.name = "garen";
            
             try {
                 //获取类HeroPlus的名字叫做name的字段
                 Field f1= h.getClass().getDeclaredField("name");
                 //修改这个字段的值
                 f1.set(h, "teemo");
                 //打印被修改后的值
                 System.out.println(h.name);
                  
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
             }
     }
    }
    

    补充:
    getField和getDeclaredField的区别
       getField 只能获取public的,包括从父类继承来的字段。
       getDeclaredField 可以获取本类所有的字段,包括private的,但是 不能获取继承来的字段。 (注: 这里只能获取到private的字段,但并不能访问该private字段的值,除非加上setAccessible(true))
     

4: 获取成员方法并使用


1 获取HeroPlus类的对象 h
2 获取成员方法:
public Method getMethod(String name ,Class<?>… parameterTypes):获取"公有方法";(包含了父类的方法也包含Object类)
public Method getDeclaredMethods(String name ,Class<?>… parameterTypes) :获取成员方法,包括私有的(不包括继承的)
参数解释:
  name : 方法名;
  Class … : 形参的Class类型对象
3 调用方法
Method --> public Object invoke(Object obj,Object… args):
参数说明:
  obj : 要调用方法的对象;
  args:调用方式时所传递的实参;
 

示例: 

package test;
public class MethodTest {
	public static void main(String[] args) {
	
	 HeroPlus h = new HeroPlus();
	 
     try {
         // 获取这个名字叫做setName,参数类型是String的方法
         Method m = h.getClass().getMethod("setName", String.class);
         // 对h对象,调用这个方法
         m.invoke(h, "盖伦");
         // 使用传统的方式,调用getName方法
         System.out.println(h.getName());

     } catch (Exception e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
     }

 }
}

5: 获取main方法并使用

示例:

  1. HeroPlus 新增main方法
public static void main(String[] args) {
		System.out.println("执行main方法");
	}
  1. 通过下面步骤获取main方法1
package test;
public class MainTest {
	public static void main(String[] args) {
		try {
			//1、获取HeroPlus对象的字节码
			Class clazz = Class.forName("pojo.HeroPlus");
			
			//2、获取main方法,第一个参数:方法名称,第二个参数:方法形参的类型,
			 Method methodMain = clazz.getMethod("main", String[].class);
			//3、调用main方法
			// methodMain.invoke(null, new String[]{"a","b","c"});
			//第一个参数,对象类型,因为方法是static静态的,所以为null可以,第二个参数是String数组,这里要注意在jdk1.4时是数组,jdk1.5之后是可变参数
			//这里拆的时候将  new String[]{"a","b","c"} 拆成3个对象。所以需要将它强转。
			 methodMain.invoke(null, (Object)new String[]{"a","b","c"});//方式一
			// methodMain.invoke(null, new Object[]{new String[]{"a","b","c"}});//方式二
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		
	}
}

4 : 关于反射的用法举例 


 反射非常强大,但是从上面的记录来看,反而觉得还不如直接调用方法来的直接和方便2。

 通常来说,需要在学习了Spring 的依赖注入,反转控制之后,才会对反射有更好的理解,所以先这里举两个例子,来演示一下反射的一种实际运用3。

1:通过反射运行配置文件内容 

首先准备两个业务类

package service;
public class Service1 {
    public void doService1(){
        System.out.println("业务方法1");
    }
}

package service;
public class Service2 {
	public void doService2(){
        System.out.println("业务方法2");
    }
}

  1. 当需要从第一个业务方法切换到第二个业务方法的时候,使用非反射方式,必须修改代码,并且重新编译运行,才可以达到效果
package service;
public class CommonTest {
	  public static void main(String[] args) {
		  //new Service1().doService1();
		  //必须重新修改代码
	        new Service2().doService2();
	    }
}
  1. 使用反射方式则方便很多

1 首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。
里面存放的是类的名称,和要调用的方法名。首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。里面存放的是类的名称,和要调用的方法名。
2 在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。
3 当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。
 

示例:
spring.txt内容

class=reflection.Service1
method=doService1

测试类

package service;
public class ReflectTest {
	@SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) throws Exception {
 
        //从spring.txt中获取类名称和方法名称
        File springConfigFile = new File("H:\\eclpise-workspace\\reflect-demo\\src\\spring.txt");
        Properties springConfig= new Properties();
        springConfig.load(new FileInputStream(springConfigFile));
        String className = (String) springConfig.get("class");
        String methodName = (String) springConfig.get("method");
         
        //根据类名称获取类对象
        Class clazz = Class.forName(className);
        //根据方法名称,获取方法对象
        Method m = clazz.getMethod(methodName);
        //获取构造器
        Constructor c = clazz.getConstructor();
        //根据构造器,实例化出对象
        Object service = c.newInstance();
        //调用对象的指定方法
        m.invoke(service);
         
    }
}

2:通过反射越过泛型检查

  泛型是在编译期间起作用的。在编译后的.class文件中是没有泛型的。所有比如T或者E类型啊,本质都是通过Object处理的。所以可以通过使用反射来越过泛型。

示例:

package test;
public class GenericityTest {
	public static void main(String[] args) throws Exception{
		
	ArrayList<String> list = new ArrayList<>();
	list.add("this");
	list.add("is");
	
	//	strList.add(5);报错
	
	/********** 越过泛型检查    **************/
	
	//获取ArrayList的Class对象,反向的调用add()方法,添加数据
	Class listClass = list.getClass(); 
	//获取add()方法
	Method m = listClass.getMethod("add", Object.class);
	//调用add()方法
	m.invoke(list, 5);
	
	//遍历集合
	for(Object obj : list){
		System.out.println(obj);
		}
	}

}

GitHub源码:java反射


  1. Java基础之—反射(非常重要) ↩︎

  2. 反射有什么用 ↩︎

  3. 深入分析Java方法反射的实现原理
    后记:
      本文部分内容引用自csdn的敬业的小码哥How2jJava,如有侵权,请联系我 ↩︎

文章3

java.lang.reflect.Field.getAnnotation()方法示例 -java.lang.reflect包教程™

获取注解类然后强转成目标类

作者: 初生不惑 

如果存在这样的注释,则java.lang.reflect.Field.getAnnotation(Class <T> annotationClass)方法返回指定类型的元素的注释,否则返回为null

声明

以下是java.lang.reflect.Field.getAnnotation(Class <T> annotationClass)方法的声明。

public <T extends Annotation> T getAnnotation(Class<T> annotationClass)

Java

参数

  • annotationClass - 如果给定的注释类为null

返回值

  • 该元素的注释指定的注释类型,如果存在于此元素,否则返回null

异常

  • NullPointerException - 如果指定的对象为null,该字段为实例字段。

例子

以下示例显示java.lang.reflect.Field.getAnnotation(Class<T> annotationClass)方法的用法。

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;

public class GetAnnotation {

   public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
      Field field = SampleClass.class.getField("sampleField");
      Annotation annotation = field.getAnnotation(CustomAnnotation.class);
      if(annotation instanceof CustomAnnotation){
         CustomAnnotation customAnnotation = (CustomAnnotation) annotation;
         System.out.println("name: " + customAnnotation.name());
         System.out.println("value: " + customAnnotation.value());
      }
   }
}

@CustomAnnotation(name="SampleClass",  value = "Sample Class Annotation")
class SampleClass {

   @CustomAnnotation(name="sampleClassField",  value = "Sample Field Annotation")
   public String sampleField;

   public String getSampleField() {
      return sampleField;
   }

   public void setSampleField(String sampleField) {
      this.sampleField = sampleField;
   }
}

@Retention(RetentionPolicy.RUNTIME)
@interface CustomAnnotation {
   public String name();
   public String value();
}

//原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/javareflect/javareflect_field_getannotation.html

让我们编译并运行上面的程序,这将产生以下结果 -

name: sampleClassField
value: Sample Field Annotation

//原文出自【易百教程】,商业转载请联系作者获得授权,非商业转载请保留原文链接:https://www.yiibai.com/javareflect/javareflect_field_getannotation.html
 

文章四

Java-Java反射_小小工匠的技术博客_51CTO博客

package com.xgj.master.ioc.reflect;

public class Car {

    private String brand ;
    private String color;
    private int speed;

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getSpeed() {
        return speed;
    }

    public void setSpeed(int speed) {
        this.speed = speed;
    }

    /**
     * 

     * @Title:Car

     * @Description:默认构造函数
     */
    public Car(){

    }

    /**
     * 

     * @Title:Car

     * @Description:带参构造函数

     * @param brand
     * @param color
     * @param speed
     */
    public Car(String brand ,String color ,int speed){
        this.brand = brand;
        this.color = color;
        this.speed = speed;
    }

    public void introduceCar(){
        System.out.println("Car : " + this.brand + " , " + this.color + " , " + this.speed);
    }

}
-----------------------------------

package com.xgj.master.ioc.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ReflectTest {

    public static Car initCarByDefaultConstrut() throws Exception {

        // (1)通过类装载器获取Car类对象
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class claz = loader.loadClass("com.xgj.master.ioc.reflect.Car");

        // (2)获取类的默认构造函数,并通过它实例化Car
        Constructor constructor = claz.getDeclaredConstructor(null);
        Car car = (Car) constructor.newInstance();

        // (3)通过反射方法设置属性
        Method method = claz.getMethod("setBrand", String.class);
        method.invoke(car, "BMW");

        Method method2 = claz.getMethod("setColor", String.class);
        method2.invoke(car, "black");

        Method method3 = claz.getMethod("setSpeed", int.class);
        method3.invoke(car, 100);

        return car;

    }

    public static void main(String[] args) throws Exception {

        initCarByDefaultConstrut().introduceCar();
    }

}
-----------------------------------
©著作权归作者所有:来自51CTO博客作者小小工匠的原创作品,请联系作者获取转载授权,否则将追究法律责任
Java-Java反射
https://blog.51cto.com/u_15239532/5204285

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值