能够将任意一个对象的属性名和属性值写到文件中去。不管这个对象有多少个属性,也不管这个对象的属性名是否相同。
public class Test1Class{
public static void main(String[] args){
Class c1 = Student.class;
System.out.println(c1.getName()); //获取全类名
System.out.println(c1.getSimpleName()); //获取简单类名
Class c2 = Class.forName("com.itheima.d2_reflect.Student");
System.out.println(c1 == c2); //true
Student s = new Student();
Class c3 = s.getClass();
System.out.println(c2 == c3); //true
}
}
package Reflect;
public class Test1Class {
private String name;
private int age;
private Test1Class() {
}
public Test1Class(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Test1Class{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
package Reflect;
import org.junit.Test;
import java.lang.reflect.Constructor;
public class Test1 {
@Test
public void testget(){
Class c=Test1Class.class;
Constructor[] constructor=c.getDeclaredConstructors();
for (Constructor constructor1 : constructor) {
System.out.println(constructor1.getName()+" "+constructor1.getParameterCount());
}
}
@Test
public void testget2() throws Exception {
Class c2=Test1Class.class;
Constructor constructor2=c2.getDeclaredConstructor();
constructor2.setAccessible(true);
Test1Class test= (Test1Class) constructor2.newInstance();
System.out.println(test);
System.out.println(constructor2.getName()+":"+constructor2.getParameterCount());
Constructor constructor3= c2.getConstructor(String.class,int.class);
System.out.println(constructor3.getName()+":"+constructor3.getName());
}
}
public @interface MyTest2{
String value(); //特殊属性
int age() default 10;
}
1.MyTest1注解本质上是接口,每一个注解接口都继承子Annotation接口
2.MyTest1注解中的属性本质上是抽象方法
3.@MyTest1实际上是作为MyTest接口的实现类对象
4.@MyTest1(aaa=“孙悟空”,bbb=false,ccc={“Python”,“前端”,“Java”})里面的属性值,可以通过调用aaa()、bbb()、ccc()方法获取到。
元注解是修饰注解的注解
@Target注解和@Retention注解:
@Target是用来声明注解只能用在那些位置,比如:类上、方法上、成员变量上等
@Retetion是用来声明注解保留周期,比如:源代码时期、字节码时期、运行时期
我们把获取类上、方法上、变量上等位置注解及注解属性值的过程称为解析注解。
1.如果注解在类上,先获取类的字节码对象,再获取类上的注解
2.如果注解在方法上,先获取方法对象,再获取方法上的注解
3.如果注解在成员变量上,先获取成员变量对象,再获取变量上的注解
总之:注解在谁身上,就先获取谁,再用谁获取谁身上的注解
可以实现有@MyTest注解的方法可以被框架执行,没有@MyTest注解的方法不能被框架执行。
假设现在有一个大明星叫杨超越,它有唱歌和跳舞的本领,作为大明星是要用唱歌和跳舞来赚钱的,但是每次做节目,唱歌的时候要准备话筒、收钱,再唱歌;跳舞的时候也要准备场地、收钱、再唱歌。杨超越越觉得我擅长的做的事情是唱歌,和跳舞,但是每次唱歌和跳舞之前或者之后都要做一些繁琐的事情,有点烦。于是杨超越就找个一个经济公司,请了一个代理人,代理杨超越处理这些事情,如果有人想请杨超越演出,直接找代理人就可以了。
动态代理应用举例:
/**
* 用户业务接口
*/
public interface UserService {
// 登录功能
void login(String loginName,String passWord) throws Exception;
// 删除用户
void deleteUsers() throws Exception;
// 查询用户,返回数组的形式。
String[] selectUsers() throws Exception;
}
/**
* 用户业务实现类(面向接口编程)
*/
public class UserServiceImpl implements UserService{
@Override
public void login(String loginName, String passWord) throws Exception {
if("admin".equals(loginName) && "123456".equals(passWord)){
System.out.println("您登录成功,欢迎光临本系统~");
}else {
System.out.println("您登录失败,用户名或密码错误~");
}
Thread.sleep(1000);
}
@Override
public void deleteUsers() throws Exception{
System.out.println("成功删除了1万个用户~");
Thread.sleep(1500);
}
@Override
public String[] selectUsers() throws Exception{
System.out.println("查询出了3个用户");
String[] names = {"张全蛋", "李二狗", "牛爱花"};
Thread.sleep(500);
return names;
}
}
然后为UserService生成一个动态代理对象,在动态代理中调用目标方法,在调用目标方法之前和之后记录毫秒值,并计算方法运行的时间。代码如下
public class ProxyUtil {
public static UserService createProxy(UserService userService){
UserService userServiceProxy
= (UserService) Proxy.newProxyInstance(
ProxyUtil.class.getClassLoader(),
new Class[]{UserService.class},
new InvocationHandler() {
@Override
public Object invoke( Object proxy,
Method method,
Object[] args) throws Throwable { if(
method.getName().equals("login") || method.getName().equals("deleteUsers")||
method.getName().equals("selectUsers")){
//方法运行前记录毫秒值
long startTime = System.currentTimeMillis();
//执行方法
Object rs = method.invoke(userService, args);
//执行方法后记录毫秒值
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + "方法执行耗时:" + (endTime - startTime)/ 1000.0 + "s");
return rs;
}else {
Object rs = method.invoke(userService, args);
return rs; }
} });
//返回代理对象
return userServiceProxy;
}
}
在测试类中为UserService创建代理对象
public class Test {
public static void main(String[] args) throws Exception{
// 1、创建用户业务对象。
UserService userService = ProxyUtil.createProxy(new UserServiceImpl());
// 2、调用用户业务的功能。
userService.login("admin", "123456");
System.out.println("----------------------------------");
userService.deleteUsers();
System.out.println("----------------------------------");
String[] names = userService.selectUsers();
System.out.println("查询到的用户是:" + Arrays.toString(names));
System.out.println("----------------------------------");
}
}