(三)java高级1

↘锁芯ラ 提交于 2020-02-28 19:40:10

分享以一下最近学习java的网站是:https://how2j.cn/k/reflection/reflection-usage/1111.html?p=131627
这篇文章也是根据网站的来学习。

一、关于反射机制

1.先要了解的概念

1.1.类对象概念

所有的类,都存在一个类对象,这个类对象用于提供类本身的信息,比如有几种构造方法, 有多少属性,有哪些普通方法。

类:有定义好的属性、方法的,可以完成一定功能的class
对象:类实例化,就是给类中的属性赋值,在内存中开辟一个这个类的实际的存在;

类对象:用来描述这种类,都有什么属性,什么方法的(不关对象的事情,不是实例化的)

1.2如何获取类对象

有三种,比如Hero是我们创建好的一个类
Class.forName(“package.Hero”)
Hero.class
New Hero.getClass()

2.反射机制

2.1 使用反射机制获取对象

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

package reflection;
import java.lang.reflect.Constructor;
import charactor.Hero;
public class TestReflection {
 
    public static void main(String[] args) {
    	//传统的使用new的方式创建对象
        Hero h1 =new Hero();
        h1.name = "teemo";
        System.out.println(h1);
         
        try {
        	//使用反射的方式创建对象
            String className = "charactor.Hero";
            //类对象
            Class pClass=Class.forName(className);
            //构造器
            Constructor c= pClass.getConstructor();
            //通过构造器实例化
            Hero h2= (Hero) c.newInstance();
            h2.name="gareen";
            System.out.println(h2);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

2.2反射有什么用

反射非常强大,但是学习了之后,会不知道该如何使用,反而觉得还不如直接调用方法来的直接和方便。

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

2.2.1业务类

首先准备两个业务类,这两个业务类很简单,就是各自都有一个业务方法,分别打印不同的字符串
Service1.java

package reflection;

public class Service1 {
	public void doService1() {
		System.out.println("正在使用业务方法1完成业务1");
	}

}

Service2.java

package reflection;

public class Service2 {
	public void doService2() {
		System.out.println("正在使用业务方法2完成业务2");
	}
}

2.2.2非反射方式

当需要从第一个业务方法切换到第二个业务方法的时候,使用非反射方式,必须修改代码,并且重新编译运行,才可以达到效果
Test.java

package reflection;
 
public class Test {
 
    public static void main(String[] args) {
        new Service1().doService1();
    }
}

切换业务时修改代码:
Test.java

package reflection;
 
public class Test {
 
    public static void main(String[] args) {
//      new Service1().doService1();
        new Service2().doService2();
    }
}

2.2.3反射方式

使用反射方式,首先准备一个配置文件,就叫做spring.txt吧, 放在src目录下。 里面存放的是类的名称,和要调用的方法名。
在测试类Test中,首先取出类名称和方法名,然后通过反射去调用这个方法。

当需要从调用第一个业务方法,切换到调用第二个业务方法的时候,不需要修改一行代码,也不需要重新编译,只需要修改配置文件spring.txt,再运行即可。

这也是Spring框架的最基本的原理,只是它做的更丰富,安全,健壮。

2.2.3.1当使用业务方法1时

业务1对应spring.txt
SpringTest.java

package reflection;

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

public class SpringTest {
	
	@SuppressWarnings({"rawtypes","unchecked"})//告诉编译器忽略指定的警告,不用在编译完成后出现警告信息
	
	public static void main(String[] args) throws Exception {
		
		//从spring.txt中获取类名称和方法名称
		File springConfigFile=new File("D:\\java\\eclipse\\eclipse-workspace\\j2se\\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);
	}
}

运行结果:
业务1

2.2.3.2切换到业务2时

只需要修改spring.txt中的内容
业务2对应spring.txt
而不用修改SpringTest.java中的代码
运行结果:
业务2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!