一、注解
/**
* 元注解
*/
@MyAnnotation
public class Demo01 {
@MyAnnotation
public void test(){
}
}
//自定义一个注解
//@Target表示注解可以用在哪些地方 下面的例子表面可以用在类以及方法上
@Target(value = {ElementType.TYPE,ElementType.METHOD})
//@Retention 表示在什么地方注解还有效 source<class<runtime 若是source 则表明注解在源码中有效
// 编译后形成class文件后注解无效,通常采用runtime
@Retention(value = RetentionPolicy.RUNTIME)
//@Documented 表示是否将注解生成在javadoc中
@Documented
//@Inherited 表示子类可以继承父类的注解
@Inherited
@interface MyAnnotation{//注意一个类里面只要能有一个public 所以此注解不可以加上public 会报错
}
/**
* 自定义注解
*/
@MyAnnotation3("zzz")
public class Demo02 {
@MyAnnotation2(num=10,name="zfc")//注解的参数没有顺序
public void test(){
}
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
String name();//注意这不是方法 这是注解的参数 如果注解有参数 那么在使用时 必须写明参数 否则报错
int age() default 0;//当然也可以写明参数 这样的话使用时可以不写
int num();
String[] schools() default {"西交大","西电"};
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value();//如果注解只有一个参数 那么使用value,并且在使用时可以省略value,只写参数 其他的则不行
}
二、反射
- 获得反射对象
反射就是通过对象反射求出类名的过程
public class Demo01 {
public static void main(String[] args)throws ClassNotFoundException {
//通过反射获取类的class对象
Class c1 = Class.forName("reflection.User");
System.out.println(c1);
Class c2 = Class.forName("reflection.User");
Class c3 = Class.forName("reflection.User");
Class c4 = Class.forName("reflection.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());//所有的hashcode都一样 因此一个类只有一个class对象并且一个类被加载后,其类结构就会被封装在class对象中
}
}
public static void main(String[] args) throws ClassNotFoundException{
Student student = new Student();
//方式一:通过对象获得class类对象
Class c1 = student.getClass();
System.out.println("c1:"+c1.hashCode());
//方式二:通过forname获得class类对象
Class c2 = Class.forName("reflection.Student");
System.out.println("c2:"+c2.hashCode());
//方式三:通过类名.class获得class类对象
Class c3 = Student.class;
System.out.println("c3:"+c3.hashCode());
//获得父类
Class superclass = c1.getSuperclass();
System.out.println(superclass);
}
- 获取类的信息
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
/**
* 总结:1.不带Declared是获取共有,带Declared是公有私有都会获取
* 2.带参数的是获得指定的,不带参数的是获得所有
*/
Class c1 = Class.forName("reflection.User");
//获取包名+类名
String name = c1.getName();
System.out.println("包名+类名:"+name);
//获取类名
String simpleName = c1.getSimpleName();
System.out.println("类名:"+simpleName);
//获取所有属性
Field[] fields =c1.getFields();//获得所有公有属性
for (Field field : fields) {
System.out.println("公有属性:"+field);
}
Field[] declaredFields = c1.getDeclaredFields();//获得所有属性公有+私有
for (Field declaredField : declaredFields) {
System.out.println("公有+私有属性:"+declaredField);
}
//获得指定属性
Field sch = c1.getField("sch");//这个是获得指定的公有属性
System.out.println("获得指定属性:"+sch);
Field id = c1.getDeclaredField("id");//这个是获得指定的属性 私有和公有
System.out.println("获得指定属性:"+id);
//获得方法
Method[] methods = c1.getMethods();//获得本类和父类的所有公有方法
for (Method method : methods) {
System.out.println("获得方法:"+method);
}
System.out.println("-------------------------------------------");
Method[] declaredMethods = c1.getDeclaredMethods();//获得本类的所有私有和公有方法
for (Method declaredMethod : declaredMethods) {
System.out.println("获得方法:"+declaredMethod);
}
//获得指定方法
Method getAge = c1.getMethod("getAge");//获得指定的共有方法
System.out.println("获得指定方法:"+getAge);
Method setAge = c1.getDeclaredMethod("setAge", int.class);//获得指定的私有公有方法
System.out.println("获得指定方法:"+setAge);
//获得构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println("获得所有构造器:"+constructor);
}
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println("获得所有构造器:"+constructor);
}
//获得指定构造器
Constructor constructor = c1.getConstructor(String.class, int.class, int.class, String.class);
System.out.println("获得指定构造器:"+constructor);
}
通过反射获取对象、操作对象
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException,NoSuchMethodException, InvocationTargetException,NoSuchFieldException{
//根据class对象创建一个类的对象
Class c1 = Class.forName("reflection.User");
User user = (User) c1.newInstance();//默认创建出来是object类型 但已知是创建的user 因此转换成user
System.out.println(user);//打印出来的属性都是空值 本质上是调用了无参构造函数 如果将类里面的无参构造函数 删除 则程序会报错
//User{name='null', id=0, age=0}
//根据构造器创建对象 可以对对象的属性赋值
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
User user1 = (User)declaredConstructor.newInstance("ZZZ", 001, 20);
System.out.println(user1);//User{name='ZZZ', id=1, age=20}
//操作对象的方法
//获取方法
Method declaredMethod = c1.getDeclaredMethod("setAge", int.class);
//激活方法
declaredMethod.invoke(user1,100);
System.out.println(user1);//User{name='ZZZ', id=1, age=100}
//操作对象的属性
//获取属性
Field name = c1.getDeclaredField("name");
//如果删除这句话 则会报错 因为无法操作私有属性 因此必须加上这句话 关闭安全检测
name.setAccessible(true);
//操作属性
name.set(user1,"ddd");
System.out.println(user1);//User{name='ddd', id=1, age=100}
}
通过反射获取注解
public static void main(String[] args) throws ClassNotFoundException,NoSuchFieldException{
Class c1 = Class.forName("reflection.Demo05");
//获取类的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取指定注解的值
// Annotation5 annotation = (Annotation5) c1.getAnnotation(Annotation5.class);
// String value = annotation.value();
// System.out.println(value);
//获得指定属性的注解
// Field name = c1.getDeclaredField("age");
// Annotation6 annotation1 = name.getAnnotation(Annotation6.class);
// System.out.println(annotation1.column());
// System.out.println(annotation1.length());
// System.out.println(annotation1.type());
}
}
@Annotation5("db_Teacher")
class Teacher {
@Annotation6(column = "db_name",type = "varchar",length = 3)
private String name;
@Annotation6(column = "db_age",type = "int",length = 3)
private int age;
public Teacher() {
}
public Teacher(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 "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Annotation5 {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Annotation6 {
String column();
String type();
int length();
}