第17章_反射机制拓展练习(关于Class,反射的应用,综合练习)

news2024/12/28 23:36:54

文章目录

  • 第17章_反射机制拓展练习
    • 关于Class
      • 1、获取Class对象
    • 反射的应用
      • 2、创建对象
      • 3、修改属性值
      • 4、调用方法
      • 5、获取类型信息
      • 6、榨汁机
      • 7、获取泛型参数
      • 8、自定义注解1
      • 9、自定义注解2
    • 综合练习
      • 10、AtguiguDemo
      • 11、AtguiguStudent
      • 12、自定义注解

第17章_反射机制拓展练习


关于Class

1、获取Class对象

使用4种方式获取java.time.LocalDate类的Class对象,并打印输出。

package com.atguigu.exercise1;

import java.time.LocalDate;

public class Exercise1 {
    public static void main(String[] args){
        try {
            Class c1 = LocalDate.class;
            Class c2 = LocalDate.now().getClass();
            Class c3 = Class.forName("java.time.LocalDate");
            Class c4 = ClassLoader.getSystemClassLoader().loadClass("java.time.LocalDate");

            System.out.println("c1 = " + c1);
            System.out.println("c2 = " + c2);
            System.out.println("c3 = " + c3);
            System.out.println("c4 = " + c4);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

反射的应用

2、创建对象

(1)通过反射创建java.util.Date类的对象。

(2)通过反射创建java.time.LocalDate类的对象。

package com.atguigu.exercise2;

import org.junit.Test;

import java.lang.reflect.Constructor;

public class Exercise2 {
    @Test
    public void test01() throws Exception {
        Class clazz = Class.forName("java.util.Date");
        Object nowObj = clazz.newInstance();
        System.out.println(nowObj);
    }
    @Test
    public void test02() throws Exception{
        Class clazz = Class.forName("java.time.LocalDate");
        Constructor constructor = clazz.getDeclaredConstructor(int.class, int.class, int.class);
        constructor.setAccessible(true);
        Object obj = constructor.newInstance(2022, 2, 4);
        System.out.println("obj = " + obj);
    }
}

3、修改属性值

已知有如下字符串:

String str = "hello";

通过反射修改str对象的"hello"为"hallo"。

package com.atguigu.exercise3;

import java.lang.reflect.Field;

public class Exercise3 {
    public static void main(String[] args) throws Exception{
        String str = "hello";
        
        Class clazz = str.getClass();
        Field valueField = clazz.getDeclaredField("value");
        valueField.setAccessible(true);
        char[] value = (char[]) valueField.get(str);
        value[1] = 'a';

        System.out.println("str = " + str);
    }
}

4、调用方法

通过反射分别调用java.time.LocalDate的如下方法:

  • public static LocalDate now()
  • public LocalDate plusDays(long daysToAdd)
package com.atguigu.exercise4;

import java.lang.reflect.Method;

public class Exercise4 {
    public static void main(String[] args)throws Exception{
        Class clazz = Class.forName("java.time.LocalDate");
        Method nowMethod = clazz.getMethod("now");
        Object obj = nowMethod.invoke(null);
        System.out.println("obj = " + obj);

        Method plusDaysMethod = clazz.getMethod("plusDays", long.class);
        Object future = plusDaysMethod.invoke(obj, 100);
        Syste.out.println("future = " + future);
    }
}

5、获取类型信息

通过反射获取java.time.LocalDate类的详细信息。

package com.atguigu.exercise5;

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

public class Exercise5 {
    @Test
    public void test() throws ClassNotFoundException {
        //1、先得到某个类型的Class对象
        Class clazz = Class.forName("java.time.LocalDate");

        //2、获取类信息
        //(1)获取包对象,即所有java的包,都是Package的对象
        Package pkg = clazz.getPackage();
        System.out.println("包名:" + pkg.getName());

        //(2)获取修饰符
        int mod = clazz.getModifiers();
        System.out.println("类的修饰符有:" + Modifier.toString(mod));

        //(3)类型名
        String name = clazz.getName();
        System.out.println("类名:" + name);

        //(4)父类,父类也有父类对应的Class对象
        Class superclass = clazz.getSuperclass();
        System.out.println("父类:" + superclass);

        //(5)父接口们
        System.out.println("父接口们:");
        Class[] interfaces = clazz.getInterfaces();
        for (Class iter : interfaces) {
            System.out.println(iter);
        }

        //(6)类的属性,你声明的一个属性,就是一个Field的对象
        System.out.println("------------------------------");
        System.out.println("成员如下:");
        System.out.println("属性有:");
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            //修饰符、数据类型、属性名
            int modifiers = field.getModifiers();
            System.out.println("属性的修饰符:" + Modifier.toString(modifiers));

            String name2 = field.getName();
            System.out.println("属性名:" + name2);

            Class<?> type = field.getType();
            System.out.println("属性的数据类型:" + type);
        }
        System.out.println("-------------------------");
        //(7)构造器们
        System.out.println("构造器列表:");
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (int i = 0; i < constructors.length; i++) {
            Constructor constructor = constructors[i];
            System.out.println("第" + (i + 1) + "个构造器:");
            //修饰符、构造器名称、构造器形参列表  、抛出异常列表
            int modifiers = constructor.getModifiers();
            System.out.println("构造器的修饰符:" + Modifier.toString(modifiers));

            String name2 = constructor.getName();
            System.out.println("构造器名:" + name2);

            //形参列表
            System.out.println("形参列表:");
            Class[] parameterTypes = constructor.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println(parameterType);
            }

            //异常列表
            System.out.println("异常列表:");
            Class<?>[] exceptionTypes = constructor.getExceptionTypes();
            for (Class<?> exceptionType : exceptionTypes) {
                System.out.println(exceptionType);
            }
            System.out.println();
        }
        System.out.println("---------------------------------");
        //(8)方法们
        System.out.println("方法列表:");
        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            Method method = declaredMethods[i];
            System.out.println("第" + (i + 1) + "个方法:");
            //修饰符、返回值类型、方法名、形参列表 、异常列表
            int modifiers = method.getModifiers();
            System.out.println("方法的修饰符:" + Modifier.toString(modifiers));

            Class<?> returnType = method.getReturnType();
            System.out.println("返回值类型:" + returnType);

            String name2 = method.getName();
            System.out.println("方法名:" + name2);

            //形参列表
            System.out.println("形参列表:");
            Class[] parameterTypes = method.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.println(parameterType);
            }

            //异常列表
            System.out.println("异常列表:");
            Class<?>[] exceptionTypes = method.getExceptionTypes();
            for (Class<?> exceptionType : exceptionTypes) {
                System.out.println(exceptionType);
            }
            System.out.println();
        }
    }
}

6、榨汁机

案例:榨汁机(Juicer)榨汁的案例,分别有水果(Fruit)苹果(Apple)香蕉(Banana)桔子(Orange)榨汁(squeeze)

效果:

在这里插入图片描述

开发提示:

​ 1、声明(Fruit)水果接口,包含榨汁抽象方法:void squeeze();

​ 2、声明榨汁机(Juicer),包含运行方法:public void run(Fruit f),方法体中,调用f的榨汁方法squeeze()

​ 3、声明各种水果类,实现(Fruit)水果接口,并重写squeeze();

​ 4、在src下,建立配置文件:config.properties,并在配置文件中配上fruitName=xxx(其中xx为某种水果的全类名)

​ 5、在Test02测试类中,

​ (1)读取配置文件,获取水果类名,并用反射创建水果对象,

​ (2)创建榨汁机对象,并调用run()方法

package com.atguigu.exercise6;

import java.util.Properties;

public class Exercise6 {
	@Test
    public void test() throws Exception {
        Properties pro = new Properties();
        pro.load(Exercise6.class.getClassLoader().getResourceAsStream("config.properties"));
        Class<?> clazz = Class.forName(pro.getProperty("fruitName"));
        Fruit f = (Fruit) clazz.newInstance();
        Juicer j = new Juicer();
        j.run(f);
    }
}

interface Fruit {
	public void squeeze();
}

class Juicer {
	public void run(Fruit f) {
		f.squeeze();
	}

}
class Apple implements Fruit {
	public void squeeze() {
		System.out.println("榨出一杯苹果汁儿");
	}
}

class Orange implements Fruit {
	public void squeeze() {
		System.out.println("榨出一杯桔子汁儿");
	}
}


7、获取泛型参数

代码填空题

package com.atguigu.exercise7;

import java.lang.reflect.ParameterizedType;

public class Exercise7 {
	public static void main(String[] args) {
		SubA a = new SubA();
		System.out.println(a.getType());
		
		SubB b = new SubB();
		System.out.println(b.getType());
	}
}
abstract class Base<T>{
	private Class type;
	
	public Base(){
		//为type属性赋值为T的实际类型
        
        _____________________________________
	}

	public Class getType() {
		return type;
	}
}
class SubA extends Base<String>{

}
class SubB extends Base{

}
package com.atguigu.exercise7;

import java.lang.reflect.ParameterizedType;

public class Exercise7 {
	public static void main(String[] args) {
		SubA a = new SubA();
		System.out.println(a.getType());
		
		SubB b = new SubB();
		System.out.println(b.getType());
	}
}
abstract class Base<T>{
	private Class type;
	
	public Base(){
		Class<? extends Base> clazz = this.getClass();
		try {
			ParameterizedType pt = (ParameterizedType) clazz.getGenericSuperclass();
			type = (Class) pt.getActualTypeArguments()[0];
		} catch (Exception e) {
			type = Object.class;
		}
	}

	public Class getType() {
		return type;
	}
}
class SubA extends Base<String>{

}
class SubB extends Base{

}

8、自定义注解1

(1)声明自定义注解类型MyAnnotation,

  • 注解使用位置只能是方法上面
  • 注解声明周期为RetentionPolicy.RUNTIME
  • 注解包含抽象方法:String value();

(2)在主方法上标记MyAnnotation注解,并且为抽象方法value()指定返回值“主方法”

(3)在主方法中读取MyAnnotation注解信息,并调用value()抽象方法获取返回值,打印返回值。

package com.atguigu.exercise8;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

package com.atguigu.exercise8;

import java.lang.reflect.Method;

public class Exercise8 {
    @MyAnnotation("主方法")
    public static void main(String[] args) {
        try {
            Class clazz = Exercise8.class;
            Method mainMethod = clazz.getMethod("main", String[].class);
            MyAnnotation myAnnotation = mainMethod.getAnnotation(MyAnnotation.class);
            String value = myAnnotation.value();
            System.out.println("value = " + value);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

9、自定义注解2

案例:

​ 1、声明自定义注解@Table

​ (1)加上String类型的配置参数value

​ (2)并限定@Table的使用位置为类上

​ (3)并指定生命周期为“运行时”

​ 2、声明自定义注解@Column

​ (1)加上String类型的配置参数name,表示表格的列名

​ (2)加上String类型的配置参数type,表示表格的列数据类型

​ (3)并限定@Column的使用位置在属性上

​ (4)并指定生命周期为“运行时”

​ 3、声明User类,

​ (1)属性:id, username, password, email

​ (2)在User类上,标记@Table注解,并为value赋值为"t_user"

​ (3)在User类的每一个属性上标记@Column,并为name和type赋值,例如:

​ id:name赋值为no,type赋值为int

​ username:name赋值为username,type赋值为varchar(20)

​ password:name赋值为pwd,type赋值为char(6)

​ email:name赋值为email,type赋值为varchar(50)

​ 4、在测试类Test04中,通过反射,获取User类以及每一个属性声明的注解,并获取注解值

​ 运行效果:

在这里插入图片描述

package com.atguigu.exercise9;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Table {
	String value();
}

package com.atguigu.Exercise9;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
	String name();
	String type();
}
package com.atguigu.exercise9;

@Table("t_user")
public class User {
	@Column(name="no",type="int")
	private int id;
	
	@Column(name="username",type="varchar(20)")
	private String username;
	
	@Column(name="pwd",type="char(6)")
	private String password;
	
	@Column(name="email",type="varchar(50)")
	private String email;
	
	public User(int id, String username, String password, String email) {
		super();
		this.id = id;
		this.username = username;
		this.password = password;
		this.email = email;
	}
	public User() {
		super();
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + "]";
	}
	
}
package com.atguigu.exercise9;

import java.lang.reflect.Field;

public class Exercise9 {
	@Test
    public void test() throws NoSuchFieldException {
        Class clazz = User.class;

        Table t = (Table) clazz.getAnnotation(Table.class);
        String table = t.value();
        System.out.println("User类对应数据库表:" + table);

        Field idField = clazz.getDeclaredField("id");
        Column idColumn = idField.getAnnotation(Column.class);
        String idName = idColumn.name();
        String idType = idColumn.type();
        System.out.println("id属性对应数据库表的字段:" + idName + ",类型:" + idType);

        Field usernameField = clazz.getDeclaredField("username");
        Column usernameColumn = usernameField.getAnnotation(Column.class);
        String usernameName = usernameColumn.name();
        String usernameType = usernameColumn.type();
        System.out.println("username属性对应数据库表的字段:" + usernameName + ",类型:" + usernameType);

        Field passwordField = clazz.getDeclaredField("password");
        Column passwordColumn = passwordField.getAnnotation(Column.class);
        String passwordName = passwordColumn.name();
        String passwordType = passwordColumn.type();
        System.out.println("password属性对应数据库表的字段:" + passwordName + ",类型:" + passwordType);

        Field emailField = clazz.getDeclaredField("email");
        Column emailColumn = emailField.getAnnotation(Column.class);
        String emailName = emailColumn.name();
        String emailType = emailColumn.type();
        System.out.println("email属性对应数据库表的字段:" + emailName + ",类型:" + emailType);
    }
}

综合练习

10、AtguiguDemo

案例:用反射获取某个类的信息,并用反射使用某个类

开发提示:

​ 1、声明一个类:com.atguigu.test01.demo.AtguiguDemo,

​ (1)包含静态变量:学校school(显式初始化为"尚硅谷")

​ (2)包含属性:班级名称className

​ (3)并提供构造器,get/set等

​ (4)实现Serializable和Comparable接口(按照班级名称排序)

​ 2、把com.atguigu.test01.demo.Exercise10class导出为一个atguigu.jar并放到D:\ProgramFiles\Java\jdk1.8.0_141\jre\lib\ext目录(注意,以你自己的JDK安装目录为准)

​ 3、在测试类Test01的test01()测试方法中,用反射获取AtguiguDemo类的Class对象,并获取它的所有信息,包括类加载器、包名、类名、父类、父接口、属性、构造器、方法们等。

​ 4、在测试类Test01的test02()测试方法中,用反射获取school的值,并修改school的值为“尚硅谷大学”,然后再获取school的值

​ 5、在测试类Test01的test03()测试方法中,用反射创建AtguiguDemo类的对象,并设置班级名称className属性的值,并获取它的值

​ 6、在测试类Test01的test04()测试方法中,用反射获取有参构造创建2个AtguiguDemo类的对象,并获取compareTo方法,调用compareTo方法,比较大小。

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays;

import org.junit.Test;

public class Exercise10 {
	@Test
	public void test01() throws ClassNotFoundException{
		Class clazz = Class.forName("com.atguigu.test01.demo.AtguiguDemo");
		
		ClassLoader classLoader = clazz.getClassLoader();
		System.out.println("类加载器:" + classLoader);
		
		Package pkg = clazz.getPackage();
		System.out.println("包名:" + pkg.getName());
		
		int cMod = clazz.getModifiers();
		System.out.println("类的修饰符:" + Modifier.toString(cMod));
		
		System.out.println("类名:" + clazz.getName());
		System.out.println("父类:" + clazz.getSuperclass().getName());
		Class[] interfaces = clazz.getInterfaces();
		System.out.println("父接口们:"+Arrays.toString(interfaces));
		
		Field[] declaredFields = clazz.getDeclaredFields();
		for (int i =0 ;i<declaredFields.length; i++) {
			System.out.println("第" + (i+1) + "个字段:");
			int fMod = declaredFields[i].getModifiers();
			System.out.println("修饰符:" + Modifier.toString(fMod));
			System.out.println("数据类型:"  + declaredFields[i].getType().getName());
			System.out.println("属性名:" + declaredFields[i].getName());
		}
		
		Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
		for (int i = 0; i < declaredConstructors.length; i++) {
			System.out.println("第" + (i+1) + "个构造器:");
			int csMod = declaredConstructors[i].getModifiers();
			System.out.println("修饰符:" + Modifier.toString(csMod));
			System.out.println("构造器名:" + declaredConstructors[i].getName());
			System.out.println("形参列表:" + Arrays.toString(declaredConstructors[i].getParameterTypes()));
		}
		
		Method[] declaredMethods = clazz.getDeclaredMethods();
		for (int i = 0; i < declaredMethods.length; i++) {
			System.out.println("第" + (i+1) + "个成员方法:");
			int csMod = declaredMethods[i].getModifiers();
			System.out.println("修饰符:" + Modifier.toString(csMod));
			System.out.println("返回值类型:" + declaredMethods[i].getReturnType().getName());
			System.out.println("方法名:" + declaredMethods[i].getName());
			System.out.println("形参列表:" + Arrays.toString(declaredMethods[i].getParameterTypes()));
		}
	}
	
	@Test
	public void test02() throws Exception{
		Class clazz = Class.forName("com.atguigu.test01.demo.AtguiguDemo");
		Field field = clazz.getDeclaredField("school");
		field.setAccessible(true);
		Object value = field.get(null);
		System.out.println("school = " + value);
		
		field.set(null, "尚硅谷大学");
		value = field.get(null);
		System.out.println("school = " + value);
	}
	
	@Test
	public void test03() throws Exception{
		Class clazz = Class.forName("com.atguigu.test01.demo.AtguiguDemo");
		Object object = clazz.newInstance();
		Field field = clazz.getDeclaredField("className");
		field.setAccessible(true);
		Object value = field.get(object);
		System.out.println("className = " + value);
		
		field.set(object, "190513班");
		value = field.get(object);
		System.out.println("className = " + value);
	}
	
	@Test
	public void test04() throws Exception{
		Class clazz = Class.forName("com.atguigu.test01.demo.AtguiguDemo");
		Constructor c = clazz.getDeclaredConstructor(String.class);
		Object obj1 = c.newInstance("190513BJ班");
		Object obj2 = c.newInstance("190325SH班");
		
		Method m = clazz.getDeclaredMethod("compareTo", Object.class);
		System.out.println("obj1与obj2比较结果:" + m.invoke(obj1, obj2));
	}
}

package com.atguigu.exercise10;

import java.io.Serializable;

public class AtguiguDemo implements Serializable,Comparable<AtguiguDemo>{
	private static final long serialVersionUID = 1L;
	private static String school = "尚硅谷";
	private String className;
	public AtguiguDemo(String className) {
		super();
		this.className = className;
	}
	public AtguiguDemo() {
		super();
	}
	public static String getSchool() {
		return school;
	}
	public static void setSchool(String school) {
		AtguiguDemo.school = school;
	}
	public String getClassName() {
		return className;
	}
	public void setClassName(String className) {
		this.className = className;
	}
	@Override
	public String toString() {
		return "AtguiguDemo [className=" + className + "]";
	}
	@Override
	public int compareTo(AtguiguDemo o) {
		return this.className.compareTo(o.getClassName());
	}
}

11、AtguiguStudent

(1)声明一个尚硅谷学生类AtguiguStudent,

  • 包含静态变量:学校school

  • 包含属性:班级名称className

  • 并提供构造器,get/set等

  • 实现Serializable

  • 实现Comparable接口,重写int compareTo(T t)方法按照班级名称排序

(2)在测试类的test01()测试方法中,用反射获取AtguiguStudent类的Class对象,并获取它的所有信息,包括类加载器、包名、类名、父类、父接口、属性、构造器、方法们等。

(3)在测试类的test02()测试方法中,用反射设置school的值为“尚硅谷”,获取school的值

(4)在测试类的test03()测试方法中,用反射创建AtguiguStudent类的对象,并设置班级名称className属性的值,并获取它的值

(5)在测试类的test04()测试方法中,用反射获取有参构造创建2个AtguiguStudent类的对象,并获取compareTo方法,调用compareTo方法,比较大小。

import java.io.Serializable;

public class AtguiguStudent implements Serializable,Comparable<AtguiguStudent>{
    private static final long serialVersionUID = 1L;
    private static String school = "尚硅谷";
    private String className;
    public AtguiguStudent(String className) {
        super();
        this.className = className;
    }
    public AtguiguStudent() {
        super();
    }
    public static String getSchool() {
        return school;
    }
    public static void setSchool(String school) {
        AtguiguStudent.school = school;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
    @Override
    public String toString() {
        return "AtguiguDemo [className=" + className + "]";
    }
    @Override
    public int compareTo(AtguiguStudent o) {
        return this.className.compareTo(o.getClassName());
    }

}

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;

public class Exercise11 {
    @Test
    public void test01() throws ClassNotFoundException{
        Class clazz = Class.forName("com.atguigu.homework1.AtguiguStudent");

        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println("类加载器:" + classLoader);

        Package pkg = clazz.getPackage();
        System.out.println("包名:" + pkg.getName());

        int cMod = clazz.getModifiers();
        System.out.println("类的修饰符:" + Modifier.toString(cMod));

        System.out.println("类名:" + clazz.getName());
        System.out.println("父类:" + clazz.getSuperclass().getName());
        Class[] interfaces = clazz.getInterfaces();
        System.out.println("父接口们:"+ Arrays.toString(interfaces));

        Field[] declaredFields = clazz.getDeclaredFields();
        for (int i =0 ;i<declaredFields.length; i++) {
            System.out.println("第" + (i+1) + "个字段:");
            int fMod = declaredFields[i].getModifiers();
            System.out.println("修饰符:" + Modifier.toString(fMod));
            System.out.println("数据类型:"  + declaredFields[i].getType().getName());
            System.out.println("属性名:" + declaredFields[i].getName());
        }

        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        for (int i = 0; i < declaredConstructors.length; i++) {
            System.out.println("第" + (i+1) + "个构造器:");
            int csMod = declaredConstructors[i].getModifiers();
            System.out.println("修饰符:" + Modifier.toString(csMod));
            System.out.println("构造器名:" + declaredConstructors[i].getName());
            System.out.println("形参列表:" + Arrays.toString(declaredConstructors[i].getParameterTypes()));
        }

        Method[] declaredMethods = clazz.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            System.out.println("第" + (i+1) + "个成员方法:");
            int csMod = declaredMethods[i].getModifiers();
            System.out.println("修饰符:" + Modifier.toString(csMod));
            System.out.println("返回值类型:" + declaredMethods[i].getReturnType().getName());
            System.out.println("方法名:" + declaredMethods[i].getName());
            System.out.println("形参列表:" + Arrays.toString(declaredMethods[i].getParameterTypes()));
        }
    }

    @Test
    public void test02() throws Exception{
        Class clazz = Class.forName("com.atguigu.homework1.AtguiguStudent");
        Field field = clazz.getDeclaredField("school");
        field.setAccessible(true);
        field.set(null, "尚硅谷");
        Object value = field.get(null);
        System.out.println("school = " + value);
    }

    @Test
    public void test03() throws Exception{
        Class clazz = Class.forName("com.atguigu.test01.demo.AtguiguDemo");
        Object object = clazz.newInstance();
        Field field = clazz.getDeclaredField("className");
        field.setAccessible(true);
        Object value = field.get(object);
        System.out.println("className = " + value);

        field.set(object, "190513班");
        value = field.get(object);
        System.out.println("className = " + value);
    }

    @Test
    public void test04() throws Exception{
        Class clazz = Class.forName("com.atguigu.homework1.AtguiguStudent");
        Constructor c = clazz.getDeclaredConstructor(String.class);
        Object obj1 = c.newInstance("20210513BJ班");
        Object obj2 = c.newInstance("20210325SH班");

        Method m = clazz.getDeclaredMethod("compareTo", Object.class);
        System.out.println("obj1与obj2比较结果:" + m.invoke(obj1, obj2));
    }
}

12、自定义注解

(1)声明注解类型PathAnnotation

  • 使用Target元注解限定注解使用位置:ElementType.TYPE
  • 使用Retention元注解限定注解的生命周期:RetentionPolicy.RUNTIME
  • 声明抽象方法String value()

(2)在当前模块根目录下包含一个users.properties文件,里面包含如下内容:=左边是用户名,=右边是密码

#key=value
chai=999
lin=888
yan=666
admin=123456

(3)声明抽象类MyServlet,包含抽象方法:

public abstract void service(HashMap<String,String> map)throws Exception;

(4)声明LoginServlet类,继承MyServlet类,重写service方法,遍历map,如果里面包含key为username和password的键值对,则取出对应的值,并判断它和users.properties文件中用户名和密码是否匹配,如果用户名和密码都匹配则输出“登录成功”,否则输出“登录失败”。在LoginServlet类加注解PathAnnotation(“/login”)。

(5)声明SignServlet类,继承MyServlet类,重写service方法,遍历map,如果里面包含key为username和password的键值对,则取出对应的值,并判断它和users.properties文件中用户名是否重复,如果用户名已存在则输出“注册失败”,否则输出“注册成功”,并把新的用户名和密码追加到users.properties文件新的一行。在SignServlet类加注解PathAnnotation(“/sign”)。

(6)在src包含一个servlet.properties文件,并包含

servletClass=所有MyServlet类子类的全名称(每个类使用,分割)

(7)在测试类中,

  • 创建HashMap<String,Class>集合对象pathsMap。
  • 读取servlet.properties文件,获取所有MyServlet类子类的全名称,根据“,"拆分所有类名。
  • 根据上面拆分的类名,通过Class.forName(类名)方法获取所有MyServlet类子类的Class对象,并读取在它们上面定义的PathAnnotation注解,并将PathAnnotation注解值作为key,对应的Class对象作为value存放到pathsMap中。
  • 从键盘输入用户名和密码,并创建HashMap<String,String>,添加"username=输入的用户名","password=输入的密码"两个(key,value)键值对。
  • 从键盘输入路径名,通过反射创建对应Servlet对象,并调用对应类的service方法,完成登录或注册功能。

(8)代码结构如下

在这里插入图片描述

(9)运行效果如下:

在这里插入图片描述
在这里插入图片描述

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface PathAnnotation {
    String value();
}
#key=value
chai=999
lin=888
yan=666
admin=123456
import java.util.HashMap;

public abstract class MyServlet {
    public abstract void service(HashMap<String,String>  map)throws Exception;
}

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@PathAnnotation("/login")
public class LoginServlet extends MyServlet {
    @Override
    public void service(HashMap<String,String> map) throws Exception{
        Set<Map.Entry<String, String>> entries = map.entrySet();
        String username = "";
        String password = "";
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            if("username".equals(key)){
                username = value;
            }else if("password".equals(key)){
                password = value;
            }
        }

        Properties properties = new Properties();
        properties.load(new FileInputStream("day21_homework/users.properties"));
        String value = properties.getProperty(username);
        if(value != null && password.equals(value)){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
    }
}

import java.io.FileInputStream;
import java.io.FileWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

@PathAnnotation("/sign")
public class SignServlet extends MyServlet {
    @Override
    public void service(HashMap<String, String> map) throws Exception {
        Set<Map.Entry<String, String>> entries = map.entrySet();
        String username = "";
        String password = "";
        for (Map.Entry<String, String> entry : entries) {
            String key = entry.getKey();
            String value = entry.getValue();
            if("username".equals(key)){
                username = value;
            }else if("password".equals(key)){
                password = value;
            }
        }

        Properties properties = new Properties();
        properties.load(new FileInputStream("day21_homework/users.properties"));
        String value = properties.getProperty(username);
        if(value == null){
            System.out.println("注册成功");
            FileWriter fw = new FileWriter("day21_homework/users.properties",true);
            fw.write("\r\n" + username+"="+password);
            fw.close();
        }else{
            System.out.println("注册失败");
        }
    }
}

servletClass=com.atguigu.exercise13.LoginServlet,com.atguigu.exercise13.SignServlet
package com.atguigu.exercise13;

import java.util.HashMap;
import java.util.Properties;
import java.util.Scanner;

public class Exercise13 {
    public static void main(String[] args) throws Exception{
        HashMap<String,Class> pathsMap = new HashMap<>();
        Properties properties = new Properties();
        properties.load(LoginServlet.class.getClassLoader().getResourceAsStream("servlet.properties"));
        String servletClasses = properties.getProperty("servletClass");
        String[] classNames = servletClasses.split(",");
        for (String className : classNames) {
            Class<?> clazz = Class.forName(className);
            PathAnnotation pathAnnotation = clazz.getAnnotation(PathAnnotation.class);
            if(pathAnnotation != null){
                String path = pathAnnotation.value();
                pathsMap.put(path, clazz);
            }
        }

        Scanner input = new Scanner(System.in);
        System.out.print("用户名:");
        String username = input.next();

        System.out.print("密码:");
        String password = input.next();

        System.out.print("访问路径:");
        String path = input.next();

        HashMap<String,String> map = new HashMap<>();
        map.put("username",username);
        map.put("password",password);

        Class servletClass = pathsMap.get(path);
        MyServlet servlet = (MyServlet) servletClass.newInstance();
        servlet.service(map);

        input.close();
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1394012.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AttributeError: ‘DataFrame‘ object has no attribute ‘ix‘

文章目录 报错信息报错原因解决方案 报错信息 AttributeError: DataFrame object has no attribute ix 报错原因 这个ix属性在最新的pandas版本中已经升级修改。 解决方案 修改前 column01 dataset.ix[1, roomtype] 修改后 column01 dataset.loc[:,total_price] 关注公…

芯片制造上下游产业链及其工艺

整个产业链可分为&#xff1a;设计验证&#xff0c;晶圆制造&#xff0c;封装测试 设计验证&#xff1a;系统设计&#xff0c;逻辑设计&#xff0c;电路设计&#xff0c;物理设计 晶圆制造&#xff1a;拉单晶&#xff0c;磨外圆&#xff0c;切片&#xff0c;倒角&#xff0c;…

海思3559 yolov5模型转wk详细笔记

文章目录 前言1.编译caffer1.1安装虚拟机1.2安装caffer1.3编译python接口 2.适应wk的yolov5模型训练2.1下载yolov5-6.0项目源码2.2安装yolov5-6.0运行环境2.3修改模型2.4修改数据集2.5修改模型算子2.6 模型训练 3.模型转换&#xff1a;pt->onnx->caffe->wk3.1 pt->…

Docker安装Nginx并部署MySQL容器构建

一.MySQL容器的构建 1.创建MySQL根目录及配置文件夹&data文件夹 mkdir -p mysql/{conf,data} 2.上传配置文件 将配置文件上传到conf文件夹&#xff08;数据库配置文件已放到置顶资源中&#xff09; 3.命令构建MySQL容器 /soft/mysql/conf/my.cnf:/etc/my.cnf目录为我们…

如何安装配置VisualSVN服务并实现公网访问本地服务【内网穿透】

文章目录 前言1. VisualSVN安装与配置2. VisualSVN Server管理界面配置3. 安装cpolar内网穿透3.1 注册账号3.2 下载cpolar客户端3.3 登录cpolar web ui管理界面3.4 创建公网地址 4. 固定公网地址访问 前言 SVN 是 subversion 的缩写&#xff0c;是一个开放源代码的版本控制系统…

STM32入门教程-2023版【4-1】OLED调试工具

关注 点赞 不错过精彩内容 大家好&#xff0c;我是硬核王同学&#xff0c;最近在做免费的嵌入式知识分享&#xff0c;帮助对嵌入式感兴趣的同学学习嵌入式、做项目、找工作! 一、概述 在这一节先提前介绍一下&#xff0c;在以后的教程中我们会经常用到这个显示屏&#xff0…

javaScript设计模式-工厂

它的好处是消除对象间的耦合度&#xff0c;在派生子类时提供了更大的灵活性。但盲目的把普通的构造函数扔在一边&#xff0c;并不值得提倡。如果要采一不可能另外换用一个类&#xff0c;或都不需要在运行期间在一系列可互换的类中进行选择&#xff0c;就不应该使用。这样在后期…

中仕公考:国考进面后资格复审需要准备什么?

参加国考面试的考生在资格审核阶段需要准备以下材料&#xff1a; 1、本人身份证、学生证或工作证复印件。 2、公共科目笔试准考证复印件。 3、考试报名登记表。 4、本(专)科、研究生各阶段学历、学位证书(应届毕业生没有可以暂时不提供)。 5、报名资料上填写的各类证书材料…

页面数据类型为json,后端接受json数据

项目结构 依赖pom.xml <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.8.RELEASE</version></dependency><dependency><groupId>org.springframework…

一些面试会问到的奇怪问题与面试总结

1.v-for、v-if先后顺序。 官方不建议一起使用&#xff0c;但是有时候面试的时候会问到。 在vue2中是v-for先与v-if的。 源码js编译结果&#xff1a; _c()就是vm.$createElement()&#xff0c;意思是创建一个虚拟的element&#xff0c;就是返回值是VNode。 _l就是renderlist…

C#,入门教程(18)——分支语句(switch-case)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(17)——条件语句&#xff08;if-else&#xff09;的基础知识https://blog.csdn.net/beijinghorn/article/details/124033376 1、switch概述 switch-case分支语句 可以理解为 大号 的 if-else。 switch语句以switch关键字开头&…

redis7部署集群:包含主从模式、哨兵模式、Cluster集群模式等三种模式

前言&#xff1a; redis部署集群常见的一般有三种模式&#xff1a;主从模式&#xff0c;Sentinel&#xff08;哨兵模式&#xff09;&#xff0c;Redis Cluster&#xff08;高可用Cluster集群&#xff09;&#xff0c;根据不同的需求可自定义选择部署方式。 Redis 主从模式&…

2.【Linux】(进程的状态||深入理解fork||底层剖析||task_struct||进程优先级||并行和并发||详解环境变量)

一.进程 1.进程调度 Linux把所有进程通过双向链表的方式连接起来组成任务队列&#xff0c;操作系统和cpu通过选择一个task_struct执行其代码来调度进程。 2.进程的状态 1.运行态&#xff1a;pcb结构体在运行或在运行队列中排队。 2.阻塞态&#xff1a;等待非cpu资源就绪&am…

工厂企业消防安全AI可视化视频智能监管解决方案

一、方案背景 2023年11月20日下午6时30分许&#xff0c;位于江苏省无锡市惠山区前洲街道的某公司突发严重火灾&#xff0c;共造成7人死亡。这次火灾提醒我们工业安全至关重要&#xff0c;企业都应该时刻保持警惕&#xff0c;加强安全意识和培训&#xff0c;提高应对突发事件的…

RK3568驱动指南|驱动基础进阶篇-进阶8 内核运行ko文件总结

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

DrGraph原理示教 - OpenCV 4 功能 - 形态操作

形态类型 从OpenCV图像处理基本知识来看&#xff0c;膨胀腐蚀操作后&#xff0c;还有形态操作&#xff0c;如开运算、闭运算、梯度、礼帽与黑帽&#xff0c;感觉很多&#xff0c;其实&#xff0c;本质上就是批处理操作&#xff0c;如 开运算&#xff1a;先腐蚀&#xff0c;再膨…

【不用找素材】ECS 游戏Demo制作教程(3) 1.17

一、生成墓碑 新建脚本如下&#xff1a; using Unity.Entities; using Unity.Mathematics;namespace ECSdemo {public struct GraveyardRandom : IComponentData{public Random Value;}}扩充GraveyardMono如下&#xff1a; using Unity.Entities; using Unity.Mathematics; …

AVL树 -- C++实现

AVL树 – C实现 1. AVL树的概念 二叉搜索树虽可以缩短查找的效率&#xff0c;但如果数据有序或接近有序二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下。因此&#xff0c;两位俄罗斯的数学家G.M.Adelson-Velskii和E.M.Landis在1…

MySQL表的基本插入查询操作详解

博学而笃志&#xff0c;切问而近思 文章目录 插入插入更新 替换查询全列查询指定列查询查询字段为表达式查询结果指定别名查询结果去重 WHERE 条件基本比较逻辑运算符使用LIKE进行模糊匹配使用IN进行多个值匹配 排序筛选分页结果更新数据删除数据截断表聚合函数COUNTSUMAVGMAXM…

黑马Java——字符串

1.API 1.1API概述 什么是API API (Application Programming Interface) &#xff1a;应用程序编程接口 简单理解&#xff1a;API就是别人已经写好的东西&#xff0c;我们不需要自己编写&#xff0c;直接使用即可 JavaAPI: 指的就是 JDK 中提供的各种功能的 Java类&#xff…