注解
注解有什么作用
注解可以被编译器和程序读取
注解可以对程序本身做一些解释
基本的注解
public class A extends Object {
@Override//重写注解
public String toString() {
return super.toString();
}
@Deprecated//不建议使用该方法注解
public void s() {
}
@SuppressWarnings("all")//可以用来压制编译器警告
public void sdawd() {
}
}
元注解
元注解一般用在定义注解上
java有4个基本的元注解
//自定义一个注解
@Target({ElementType.METHOD, ElementType.FIELD})//表示可以在方法,和属性上用
@Retention(RetentionPolicy.RUNTIME)//表示在运行时注解生效
@Documented //表示是否将该注解生成到javadoc中
@Inherited //子类可以继承父类的注解
@interface MyAnn {
//注解可以携带参数
String value() default "llk";//表示默认有值
}
public class A {
@MyAnn
private int id;
@MyAnn
public void t() {
}
}
反射
什么是反射
反射可以在程序运行时获取程序的一些属性和方法
一个类只有一个反射对象
反射获取对象Class
public class Doc {
}
class User extends Doc {
private int id;
public String name;
static {
System.out.println("静态资源被反射触发了");
}
public static void main(String[] args) throws ClassNotFoundException {
User user = new User();
Class<?> user1 = Class.forName("User");//方法1通过包名
Class<?> user2 = user.getClass();//方法2通过对象获取
Class<?> user3 = User.class;//方法3通过类名获取
Class<?> user4 = Class.forName("User");
//每个类会创建一个单例模式的反射对象
System.out.println(user1.hashCode() == user3.hashCode() && user2.equals(user4));//true
Class<?> i = Integer.TYPE;//方法4,缺点只有特定的类型才能这样使用
//获取父类的类型class
Class<?> superclass = user1.getSuperclass();
System.out.println(superclass);
}
}
哪些类可以有Class对象
反射会获取class对象会强制加载其内部静态资源
类加载器
class User extends Doc {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类加载器
ClassLoader classLoader = User.class.getClassLoader();
System.out.println(classLoader);
//获取扩展类加载器
ClassLoader parent = classLoader.getParent();
System.out.println(parent);
//获取根加载器
ClassLoader loader = parent.getParent();
System.out.println(loader);
//获取系统加载器可以加载的路径
String property = System.getProperty("java.class.path");
for (String s : property.split(":")) {
System.out.println(s);
}
/*
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/charsets.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/deploy.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/cldrdata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/dnsns.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jaccess.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/jfxrt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/localedata.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/nashorn.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunec.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/ext/zipfs.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/javaws.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jce.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfr.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jfxswt.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/jsse.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/management-agent.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/plugin.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/resources.jar
/Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/rt.jar
/Users/pjy/code/JAVAWEB/mytest/out/production/mytest
* */
}
}
获取类的完整信息
class User extends Doc {
private int id;
public String name;
public User() {
}
private User(String name) {
this.name = name;
}
public User(int id) {
this.id = id;
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
private void fx() {
System.out.println("xxxxxxx@qq.com");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
Class<?> user = Class.forName("User");
System.out.println(user.getName());//获取完整类名
System.out.println(user.getSimpleName());//获取类的名字
//获取公开属性
Field[] fields = user.getFields();
//获取本类所有属性
Field[] declaredFields = user.getDeclaredFields();
//获取共有方法
Method[] methods = user.getMethods();
//获取本类的所有方法
Method[] declaredMethods = user.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//获取共有指定方法 参数方法名称,和方法参数class
Method setId = user.getMethod("setId", int.class);
System.out.println(setId);
//获取本类任意指定方法
Method fx = user.getDeclaredMethod("fx");
System.out.println(fx);
System.out.println("----------------------------------------");
//获取指定的共有构造器
Constructor<?> constructor = user.getConstructor(int.class);
System.out.println(constructor);
//获取任意本类的构造器
Constructor<?> declaredConstructor = user.getDeclaredConstructor(String.class);
System.out.println(declaredConstructor);
//获取全部共有构造器
Constructor<?>[] constructors = user.getConstructors();
//获取本类所有构造器
Constructor<?>[] declaredConstructors = user.getDeclaredConstructors();
}
}
通过反射操控对象
class User extends Doc {
private int id;
public String name;
public User() {
}
private User(String name) {
this.name = name;
}
public User(int id) {
this.id = id;
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
private void fx() {
System.out.println("xxxxxxx@qq.com");
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String updateName(String name) {
return this.name = name;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//通过反射创建对象
//第一种方法
Class<User> userClass = User.class;
//此方法必须在拥有无惨构造切能被访问时才能使用
User user = userClass.newInstance();
//第二种方法
Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class);
//传入构造器所需要的参数
User user2 = declaredConstructor.newInstance("李大侠");
//通过反射调用对象方法
Method declaredMethod = userClass.getDeclaredMethod("updateName", String.class);
//对象+方法参数 返回值是被调用函数的返回值
Object re = declaredMethod.invoke(user2, "肥猫");
System.out.println(re);
//通过反射操控属性
User user3 = new User();
Field id = userClass.getDeclaredField("id");
//有可能报错访问权限不足 使用一下方法解决,true是可访问,false不能访问
id.setAccessible(true);
id.set(user3, 857);
System.out.println(user3.getId());
}
}
反射获取泛型
class User extends Doc {
public void dec(Map<String, Object> map, Collection<Integer> col) {
}
public Map<String, String> doc() {
return new HashMap<>();
}
public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, InstantiationException, IllegalAccessException {
//获取参数信息
Class<User> userClass = User.class;
Method ft = userClass.getDeclaredMethod("dec", Map.class, Collection.class);
Type[] genericParameterTypes = ft.getGenericParameterTypes();//获取方法参数
for (Type genericParameterType : genericParameterTypes) {
System.out.println(genericParameterType);
//判断是否是一个参数化类型
if (genericParameterType instanceof ParameterizedType) {
//获取泛型实际类型信息
Type[] types = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type type : types) {
System.out.println(type);//打印泛型实际类型
}
}
}
System.out.println("--------------------------------");
//获取返回信息
Method doc = userClass.getDeclaredMethod("doc");
Type genericReturnType = doc.getGenericReturnType();//获取返回值信息
System.out.println(genericReturnType);
//判断是否是一个参数化类型
if (genericReturnType instanceof ParameterizedType) {
//获取泛型实际类型信息
Type[] types = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type type : types) {
System.out.println(type);//打印泛型实际类型
}
}
}
}
获取注解信息
import java.lang.annotation.*;
import java.lang.reflect.Field;
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnnotation {
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation {
String name();
String type();
int length();
}
@ClassAnnotation("学生类")
public class Student {
@FieldAnnotation(name = "学号", type = "int", length = 20)
private int id;
@FieldAnnotation(name = "姓名", type = "String", length = 50)
private String name;
@FieldAnnotation(name = "年龄", type = "int", length = 3)
private int age;
@FieldAnnotation(name = "姓别", type = "bool", length = 1)
private boolean sex;
public static void main(String[] args) throws NoSuchFieldException {
Class<Student> studentClass = Student.class;
//获取类上的注解
Annotation[] declaredAnnotations = studentClass.getAnnotations();
for (Annotation declaredAnnotation : declaredAnnotations) {
System.out.println(declaredAnnotation);
}
//获取注解的值
ClassAnnotation classAnnotation = studentClass.getAnnotation(ClassAnnotation.class);
System.out.println(classAnnotation.value());
System.out.println("------------------------");
//获取指定类的注解
Field age = studentClass.getDeclaredField("age");
age.setAccessible(true);
FieldAnnotation fieldAnnotation = age.getAnnotation(FieldAnnotation.class);
System.out.println(fieldAnnotation.name());
System.out.println(fieldAnnotation.type());
System.out.println(fieldAnnotation.length());
}
}