JavaSE(十一)反射机制与注解
反射机制与注解
提示:以下是本篇文章正文内容,下面案例可供参考
一、反射(reflect)
反射机制相关类
1.java.lang.reflect.*;
2.java.lang.Class 代表整个字节码
3.java.lang.reflect.Method 代表字节码中的方法字节码
4.java.lang.reflect.Constructor 代表字节码中的构造方法字节码
5.java.lang.reflect.Field 代表字节码中的属性字节码
1.获取类的字节码
1.Class.forName(); 静态方法 会导致类加载,静态代码执行
2.obj.getClass() 放回obj对象的类型
3.数据类型的class属性
4.newInstance() 创建对象
实列:
public static void main(String[] args){
Class c1 = null;
try {
c1 = Class.forName("java.lang.String"); //D:\java\lib\rt.jar\java\lang\String
System.out.println(c1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String s = "abc";
Class c2 = s.getClass();
Class c3 = String.class;
System.out.println(c2 == c1); //true
System.out.println(c3 == c1); //true
}
结果为true的理解:
反编译用到的User类
public class User {
public int no;
private String name;
protected int age;
boolean sex;
public boolean login(String name,String password){
if ("admin".equals(name) && "123456".equals(password)) {
return true;
}
return false;
}
public void logout(){
System.out.println("系统已经安全退出!");
}
public User(int no, String name, int age, boolean sex) {
this.no = no;
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"no=" + no +
", name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}
2.Field
使用:
Class c = Class.forName("User");
Field nameField = c.getDeclaredField("name");
Object user = c.newInstance();
// 打破封装
nameField.setAccessible(true); //[əkˈsesəbl] 可见到的
nameField.set(user,"jackson");
System.out.println(nameField.get(user));
3.Method
Class c = Class.forName("User");
Object obj = c.newInstance();
Method loginMethod = c.getDeclaredMethod("login",String.class,String.class);
Object retValue = loginMethod.invoke(obj,"admin","123456");
System.out.println(retValue);
4.Constructor
Class c = Class.forName("User");
Constructor constructor = c.getDeclaredConstructor(int.class,String.class,int.class,boolean.class);
Object obj = constructor.newInstance(100,"jackson",18,true);
System.out.println(obj);
5.父类及接口
Class c = Class.forName("java.lang.String");
Class superClass = c.getSuperclass();
System.out.println(superClass.getName());
Class[] interfaces = c.getInterfaces();
for(Class in : interfaces){
System.out.println(in.getName());
}
6.反编译
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test{
public static void main(String[] args) throws Exception {
int i = 0;
StringBuilder s = new StringBuilder();
Class c = Class.forName("java.lang.Integer");
s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + " extends ");
s.append(c.getSuperclass().getSimpleName() + "\n");
s.append("\timplements ");
for(Class interf : c.getInterfaces()){
s.append(interf.getSimpleName() + ",");
}
if(s.toString().endsWith(",")){
s.deleteCharAt(s.length() - 1);
}
s.append("\n{\n");
for(Field field : c.getDeclaredFields()){
s.append("\t" + Modifier.toString(field.getModifiers()) + " "
+ field.getType().getSimpleName() + " " + field.getName() + ";\n");
}
for(Method method: c.getDeclaredMethods()){
s.append("\t"
+ (Modifier.toString(method.getModifiers()) == "" ? "":Modifier.toString(method.getModifiers()) + " "));
s.append(method.getReturnType().getSimpleName() + " ");
s.append(method.getName() + "(");
i = 0;
for(Class parameterTyep : method.getParameterTypes()){
s.append(parameterTyep.getSimpleName() + " par" + (i++) + ",");
}
if(s.toString().endsWith(",")){
s.deleteCharAt(s.length() - 1);
}
s.append(") {};\n");
}
for(Constructor constructor : c.getDeclaredConstructors()){
s.append("\t"
+ (Modifier.toString(constructor.getModifiers())=="" ? "" : Modifier.toString(constructor.getModifiers()) + "\t" )
+ c.getSimpleName() + "(");
i = 0;
for(Class parameterTyep : constructor.getParameterTypes()){
s.append(parameterTyep.getSimpleName() + " par" + (i++) + ",");
}
if(s.toString().endsWith(",")){
s.deleteCharAt(s.length() - 1);
}
s.append(") {};\n");
}
s.append("}");
System.out.println(s);
}
}
二、注解Annotation
引用数据类型,编译后生成class文件
[修饰符列表] @interface 注解类型名{}
1.元注解
用来标注注解类型的注解
@Target(ElementType.METHOD[元素类型]) 标注注解出现的位置
@Retention(RetentionPolicy.SOURCE[保存性策略]) 被标注的注解保存在哪里
2.内置注解
@Override 只能注解方法(编译器检查是否时重写父类的方法)
源码:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Deprecated 标记已过时
过时,表现形式:有中划线
源码:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
String since() default "";
boolean forRemoval() default false; //Removal 移除
}
3.常用类型源码
ElementType源码:
enum ElementType {
TYPE,
FIELD,
METHOD,
PARAMETER,
CONSTRUCTOR,
LOCAL_VARIABLE,
ANNOTATION_TYPE,
PACKAGE,
TYPE_PARAMETER,
TYPE_USE,
MODULE,
}
RetentionPolicy源码:
enum RetentionPolicy {
SOURCE,
CLASS,
RUNTIME //可以保留在class文件中,可以被反射机制锁读取
}
4.自定义注解
使用注解时,必须给注解属性赋值,除非赋有默认值 属性定义 String name() default "";
只有一个value()属性值,赋值时属性名可以省略
属性值类型:
基本数据类型,String,Class,及它们的数组形式,给数组赋值使用大括号,只有一个元素时,可以省略大括号
5.反射注解
//Myannotion自定义注解
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 Myannotation {
String value() default "重庆";
}
//测试类
public class Test{
public static void main(String[] args) throws Exception {
Class c = Class.forName("Test");
if(c.isAnnotationPresent(Myannotation.class)){// 判断该类是否有该注解
Myannotation myannotation = (Myannotation) c.getAnnotation(Myannotation.class);
System.out.println(myannotation.value()); //获取注解属性值
}
}
}