反射的简单实现与注解创建和使用

280 阅读1分钟

 反射

1、理解Class类

对象照镜子后可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留一个不变的Class类型的对象。一个Class对象包含了特定某个类的有关信息。

可以获取对象的构造方法,成员变量,成员方法,并给他们赋值,执行。

提高代码的灵活性,减少耦合性

Class对象只能在系统建立对象。

一个类在JVM中只会有一个Class实例。

每个类的实例都会记得自己是由哪个Class实例所生成

1: Class是什么?

Class是一个类:

public class ReflectionTest {
    @Test
    public void testClass() {
       Class clazz = null;
    }
}

​
​
//Class的定义
public final
    class Class<T> implements java.io.Serializable,
                              java.lang.reflect.GenericDeclaration,
                              java.lang.reflect.Type,
                              java.lang.reflect.AnnotatedElement {
​
.....
.....
.....
}//小写class表示是一个类类型,大写Class表示这个类的名称

获取db.properties的值给对象进行赋值

@Test
public void t2() throws Exception{
    File file=new File("db.properties") ;
    Properties properties=new Properties();
    properties.load(new FileInputStream(file));
    System.out.println(properties.getProperty("servername"));
​
    Class<?> aClass = Class.forName(properties.getProperty("servername"));
​
    System.out.println(aClass.getConstructor());
    Object obj =
            aClass.getConstructor(String.class, String.class).newInstance
                    (properties.getProperty("name"), properties.getProperty("pwd")).toString();
    System.out.println(obj);
​
    try(Socket socket=new Socket(InetAddress.getLocalHost(),8001)){
        OutputStream outputStream = socket.getOutputStream();
        String str= (String) obj;
        outputStream.write(str.getBytes(StandardCharsets.UTF_8));
    }catch (Exception e){
​
    }
}

输出结果

jdbc.username=root
jdbc.password=123456
servername=com.ycz.pojo.UserEnity
name=zhangsan
pwd=lisi

用注解反射回去给对象赋值

1、对db.properties赋值

jdbc.username=root
jdbc.password=123456

2、编写注解

package com.ycz.annotation;/*
 @author ycz
 @date 2021-10-13-16:33
*/
​
​
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
​
​
​
@Retention(RetentionPolicy.RUNTIME)
public @interface ImportDbProperties {
    String value();
​

}

3、编写dbutil,在上面弄注解

package com.ycz.util;/*
 @author ycz
 @date 2021-10-13-16:33
*/import com.ycz.annotation.ImportDbProperties;
​
import java.util.Properties;
​
@ImportDbProperties("db.properties")
public class DbUtil {
​
    private Properties properties;
​
    public Properties getProperties() {
        return properties;
    }
​
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
​
    public  void show(){
        System.out.println(properties);
    }
}

4、编写测试类

@Test
public void t1() throws Exception{
    Class<DbUtil> dbUtilClass = DbUtil.class; // 反射回去
    ImportDbProperties annotation =  dbUtilClass.getAnnotation(ImportDbProperties.class);// 获取注解
    String value = annotation.value();// 获取注解上的值
    System.out.println(value);
    Properties properties=new Properties();
    properties.load(new FileInputStream(new File(value)));//创建properties且给他赋值
​
    DbUtil dbUtil=new DbUtil();
    dbUtil.setProperties(properties);
​
    dbUtil.show();
​
​
}

结果:

db.properties
{jdbc.username=root, jdbc.password=123456}