注解
1.自定义注解
//定义一个注解
//Target表示我们的注解可以放在哪里
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//表示我们的注解在什么地方还有效
@Retention(value = RetentionPolicy.RUNTIME)
//表示是否将我们的注解生成在JAVAdoc中
@Documented
//子类可以集成父类的注解
@Inherited
@interface MyAnnotation{
}
反射
1.什么是反射
//通过反射获取类的class对象
Class c1 = Class.forName("com.kuang.reflection.User");
2.所有类型的Class
Class c1 = Object.class;
Class c2 = Comparable.class;//接口
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = Override.class;
Class c6 = ElementType.class;//枚举
Class c7 = Integer.class;
Class c8 = void.class;
Class c9 = Class.class;
3.类加载内存分析
package com.kuang.reflection;
public class Test05 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
/*
1.加载到内存,会产生一个类对应的class对象
2.链接,链接结束后m=0
3.初始化
<clinit>(){
System.out.println("A类静态代码块初始化");
m = 300;
static int m = 100;
}
m=100;
*/
}
}
class A {
static {
System.out.println("A类静态代码块初始化");
m = 300;
}
static int m = 100;
public A() {
System.out.println("A类的无参构造初始化");
}
}
4.类加载器
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent=systemClassLoader.getParent();
System.out.println(parent);
//获取扩展类加载器的父类加载器-->根加载器(C/C++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
5.反射获取类的结构
package com.kuang.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.kuang.reflection.User");
User user = new User();
c1 = user.getClass();
//获得类的名字
System.out.println(c1.getName());
System.out.println(c1.getSimpleName());
//获得类的属性
System.out.println("==================");
Field[] fields = c1.getFields();//只能找到public属性
fields = c1.getDeclaredFields();//找到全部的属性
for(Field field:fields){
System.out.println(field);
}
//获得制定属性的值
Field name = c1.getDeclaredField("name");
System.out.println(name);
System.out.println("=====================");
//获得类的方法
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 getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);
System.out.println(setName);
}
}
总结:反射很强大,可以获得许多类的信息,可以通过该方法创造对象和赋值对象等操作,可以理解为一个bug。