java反射 (复习)

package com.cn.xiaonuo.main.test.jdk; import java.lang.reflect.Field; import java.lang.reflect.Method; public class PoolTest { public static void main(String[] args) throws Exception{ //对象无权直接访问类的私有成员变量、私有成员方法 //子类对象通过反射直接给私有成员变量赋值 //子类对象通过反射直接调用执行私有成员方法 //通过反射给父类对象私有成员变量赋值 //通过反射直接调用执行父类私有成员方法 //子类对象 S s = new S(); s.setBoy(new Boy(81)); Class<? extends S> sClass = s.getClass(); //给子类私有成员变量赋值 Field sidField = sClass.getDeclaredField("sid"); sidField.setAccessible(true); sidField.set(s, 10); //调用子类私有成员方法 Method drinkMethod = sClass.getDeclaredMethod("drink"); drinkMethod.setAccessible(true); drinkMethod.invoke(s); //父类对象class Class<?> pclass = sClass.getSuperclass(); //给父类私有成员变量赋值 Field pidField = pclass.getDeclaredField("pid"); pidField.setAccessible(true); pidField.set(s, 11); Field boyField = pclass.getDeclaredField("boy"); boyField.setAccessible(true); Boy boy = (Boy)boyField.get(s); //取属性值 System.out.println(boy); //调用父类私有成员方法 Method eatMethod = pclass.getDeclaredMethod("eat"); eatMethod.setAccessible(true); eatMethod.invoke(s); System.out.println("sid: " + s.getSid()); System.out.println("pid: " + s.getPid()); } public static class P { private Integer pid; private Boy boy; public Integer getPid() { return pid; } public void setPid(Integer pid) { this.pid = pid; } public Boy getBoy() { return boy; } public void setBoy(Boy boy) { this.boy = boy; } private void eat() { System.out.println("来吃饭"); } } public static class S extends P { private Integer sid; public Integer getSid() { return sid; } public void setPid(Integer sid) { this.sid = sid; } private void drink() { System.out.println("来喝茶"); } } public static class Boy { public Boy() { } public Boy(Integer boyId) { this.boyId = boyId; } private Integer boyId; public Integer getBoyId() { return boyId; } public void setBoyId(Integer boyId) { this.boyId = boyId; } } }
注解
标签, 对代码的一种解释.
元注解
修饰注解, 约束注解, 定义注解的一部分.
@Retention 的英文意为保留期的意思。当 @Retention 应用到一个注解上的时候,它解释说明了这个注解的的存活时间。
@Target 指定注解放置的位置
@Repeatable 解决一个类上不能标注重复的注解, @Repeatable相当于指向一个容器。
@Inherited 继承的意思,但是它并不是说注解本身可以继承,而是说如果一个父类被 @Inherited 修饰过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了父类的注解。
Java 预置的注解:
@FunctionalInterface 函数式接口注解,这个是 Java 1.8 版本引入的新特性。一个具有一个方法的普通接口。
@SafeVarargs 参数安全类型注解。它是在 Java 1.7 的版本中加入的。 它的目的是提醒开发者不要用参数做一些不安全的操作,它的存在会阻止编译器产生 unchecked 这样的警告。
@SuppressWarnings 阻止警告的意思。
@Override 子类重写父类方法。
@Deprecated 这个元素是用来标记过时的元素。
注解的属性
注解的属性也叫做成员变量。注解只有成员变量,没有成员方法。
注解的成员变量在注解的定义中以“无形参的方法”形式来声明,成员变量的名字-方法名,成员变量的类型-返回值类型。
注解和反射:注解通过反射获取。
1. 首先可以通过 Class 对象的 isAnnotationPresent() 方法判断它是否应用了某个注解。
2. 然后通过 getAnnotation() 方法来获取 Annotation 对象。 或者是 getAnnotations() 方法。
注解到底有什么用?
注解是一系列元数据,它提供数据用来解释程序代码,但是注解并非是所解释的代码本身的一部分。注解对于代码的运行效果没有直接影响。
注解有许多用处,主要如下:
提供信息给编译器: 编译器可以利用注解来探测错误和警告信息
编译阶段时的处理: 软件工具可以用来利用注解信息来生成代码、Html文档或者做其它相应处理。
运行时的处理: 某些注解可以在程序运行的时候接受代码的提取
值得注意的是,注解不是代码本身的一部分。
罗永浩还是罗永浩,不会因为某些人对于他“傻x”的评价而改变,标签只是某些人对于其他事物的评价,但是标签不会改变事物本身,标签只是特定人群的手段。所以,注解同样无法改变代码本身,注解只是某些工具的的工具。
package cn.time.annontation; import java.lang.annotation.*; public class TestInherited { public static void main(String[] args) { Annotation[] annotations = B.class.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); } } @Test public class A{ } public class B extends A{ } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Inherited public @interface Test{ } }
package cn.time.annontation; import java.lang.annotation.*; import java.util.Arrays; import java.util.HashSet; import java.util.Set; public class TestRepeatable { public static void main(String[] args) { Human man = new TestRepeatable().new Human(); Class<?>[] interfaces = man.getClass().getInterfaces(); Set<Class> set = new HashSet<>(); set.addAll(Arrays.asList(interfaces)); set.add(man.getClass()); set.forEach(c -> { Person[] personArr = (Person[]) c.getAnnotationsByType(Person.class); for (Person p : personArr) { System.out.println(p.role()); } }); } @Person(role = "girl") @Person(role = "boy") // @Persons({@Person(role="girl"),@Person(role="boy")}) public class Human{ } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Persons { Person[] value(); } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Repeatable(Persons.class) public @interface Person { String role() default ""; } }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
2019-03-09 idea使用资料