目录
1.内置注解:
1.@Override:重写
2.@Deprecated:不推荐使用,或者有更好的方法
3.@SuppressWarnings:镇压警告,
2.元注解(注解其他注解):
@Data : 注在类上,提供类的get、set、equals、hashCode、canEqual、toString方法
@AllArgsConstructor : 注在类上,提供类的全参构造
@NoArgsConstructor : 注在类上,提供类的无参构造
@Setter : 注在属性上,提供 set 方法
@Getter : 注在属性上,提供 get 方法
@EqualsAndHashCode : 注在类上,提供对应的 equals 和 hashCode 方法
@Log4j/@Slf4j : 注在类上,提供对应的 Logger 对象,变量名为 log
自定义一个注解:
package 注解.annotation;
import java.lang.annotation.*;
@Myself
public class Test01 {
}
//表示我们的直接可以用在哪个地方
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//表示我们的注解在什么地方有效
@Retention(value = RetentionPolicy.RUNTIME) //runtime>class>sources
//表示是否将我们的注解生成咋iavadoc中
@Documented
//子类可以继承父类
@Inherited
@interface Myself{
//注解的参数=数据类型+属性名();
String name(); //这不是一个方法
int id() default -1; //如果为-1表示不存在
}
3.反射机制:
Class c=Class.forName("路径");
Class c =Person.class;
Person person=new Person;
Class c =person.getClass();
分析类的初始化:
通过子类对象不会引用子类加载 //父类会被加载
通过反射会引起子类加载 //父类会被加载
主动引用会引起子类加载 //父类会被加载
类加载器:
package 注解.annotation;
public class Test02 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统的类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//获取系统类加载器的父类加载器->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@1540e19d
//获取扩展类加载器的父类加载器->根加载器(C++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);//null
//测试当前类是哪个加载器加载的
ClassLoader c1 = Class.forName("注解.annotation.Test02").getClassLoader();
System.out.println(c1);//sun.misc.Launcher$AppClassLoader@18b4aac2
//测试JDK内部哪个加载器加载的
ClassLoader c2 = Class.forName("java.lang.Object").getClassLoader();
System.out.println(c2);//null
}
}
获取类运行时的结构:
通过反射获取运行时类的完整结构
Field、Method、Constructor、Superclass、Interface、Annotation
1.实现的全部接口
2.所继承的父类
3.全部的构造器
4.全部的方法
5.全部的Field(属性)
6.注解
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test08 {
public static void main(String[] args) throws Exception {
Class<?> c1 = Class.forName("cn.bloghut.reflection.User");
//获得类的名称
System.out.println(c1.getName());//获得包名+类名
System.out.println(c1.getSimpleName());//类名
//获得类的属性
System.out.println("==========================");
Field[] fields = c1.getFields();//只能找到public 修饰的属性
for (Field field : fields) {
System.out.println(field);
}
fields = c1.getDeclaredFields();//找到private 修饰的属性
for (Field field : fields) {
System.out.println(field);
}
//获取指定属性的值
//Field name = c1.getField("name");报错
Field name = c1.getDeclaredField("name");
System.out.println(name);
//获得类的方法
System.out.println("==========================");
Method[] methods = c1.getMethods();//获取本类及父类的全部public 方法
for (Method method : methods) {
System.out.println("getMethods():"+method);
}
System.out.println("==========================");
methods = c1.getDeclaredMethods();//获取本类的所有方法
for (Method method : methods) {
System.out.println("getDeclaredMethods():"+method);
}
System.out.println("==========================");
//获取指定方法
Method getName = c1.getMethod("getName");
System.out.println(getName);
Method setName = c1.getMethod("setName", String.class);
System.out.println(setName);
System.out.println("==========================");
//获取指定的构造器
Constructor<?>[] constructors = c1.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("getConstructors"+constructor);
}
System.out.println("============================");
constructors = c1.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("getDeclaredConstructors():"+constructor);
}
System.out.println("======================");
//获取指定构造器
Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
System.out.println("指定"+declaredConstructor);
}
}
4.动态创建对象:
1.创建类的对象:调用Class对象的newlnstance()方法
2.类必须有一个无参数的构造器。
3.类的构造器的访问权限需要足够
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
ass Test09 {
public static void main(String[] args) throws Exception {
//获得Class对象
Class<?> c1 = Class.forName("cn.bloghut.reflection.User");
//构造一个对象
//User user = (User)c1.newInstance();//本质上是调用了类的无参构造器
// System.out.println(user);
// Constructor<?> constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//User user2 = (User)constructor.newInstance("闲言", 1, 18);
//System.out.println(user2);
//通过反射调用普通方法
User user = (User)c1.newInstance();
//通过反射获取方法
Method setName = c1.getDeclaredMethod("setName", String.class);
//invoke : 激活的意思
setName.invoke(user,"闲言");
System.out.println(user.getName());
//通过反射操作属性
User c4 = (User)c1.newInstance();
Field field = c1.getDeclaredField("name");
//关掉检查
//反射不同直接操作私有属性,需要关闭安全简则,属性或方法的setAccessible
field.setAccessible(true); //可以提高性能
field.set(c4,"反射设置属性");
System.out.println(c4);
}
}
5.获得泛型信息:
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Test11 {
public void test01(Map<String, User> map, List<User> list) {
}
public Map<String, User> test02() {
return null;
}
public static void main(String[] args) throws Exception {
Class<Test11> c1 = Test11.class;
Method test01 = c1.getMethod("test01", Map.class, List.class);
//获取参数的泛型参数类型
Type[] genericParameterTypes = test01.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
//判断这个泛型是不是参数化类型
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
System.out.println("===================================================================");
Method method = c1.getMethod("test02");
Type type = method.getGenericReturnType();
if (type instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
//控制台打印
java.util.Map<java.lang.String, cn.bloghut.reflection.User>
class java.lang.String
class cn.bloghut.reflection.User
java.util.List<cn.bloghut.reflection.User>
class cn.bloghut.reflection.User
===================================================================
class java.lang.String
class cn.bloghut.reflection.User