注解
JDK5.0引入。和注释一样,都是用来解释说明代码的,区别就是注释是给程序员看的,注解是给程序看的。添加注解就相当于给代码添加了辅助信息,这些辅助信息可以通过反射来访问。
内置注解
常用的内置注解有三个 1、@Override:重写方法 2、@Deprecated:表明不推荐使用,但是依然可以使用 3、@SuppressWarnings:镇压警告,需要传参数。
元注解
元注解的作用就是:注解其他的注解,相当于解释其他注解的作用,Java定义了四种meta-annotation类型的注解 1、@Target:描述注解的适用范围 2、@Retention:描述注解的生命周期,表示在什么级别保存注解 3、@Document:说明注解会被包含在javadoc种 4、@Inherited:说明子类可以继承父类的注解
自定义注解
public class Test1 {
@MyAnnotation("")
public void test() {}
@MyAnnotation2(name = "")
public void test1(){}
@MyAnnotation3(name = "",person = {"清华"})
public void test3(){}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation{
String value();
}
@interface MyAnnotation2{
String name();
}
@interface MyAnnotation3{
int age() default -1;
String name() ;
String[] person();
}
类加载
当一个类被使用的时候,就需要加载类。过程可以分为三个阶段。
加载
1、获取类的二进制字节流 2、把字节流代表的静态结构转换成运行时数据结构 3、在堆生成该类的Class对象
链接
1、验证字节流中的信息是否符合虚拟机安全规范 2、为类变量(static)分配内存并设置初始值 3、将常量池中的符号引用常量替换为直接引用常量
初始化
执行类构造器方法,编译器自动收集类中所有类变量的赋值动作和静态语句块中的语句,然后合并产生的方法。 这里是类构造器,并不是构造器,比如直接输出静态变量的话,并不会执行构造器。 当类被主动引用是会发生初始化: 1、虚拟机启动会直接初始化main方法所在类。 2、new一个对象时,对象的类会被初始化 3、调用类的静态变量和静态方法(调用静态常量不会) 4、反射 5、初始化类时,如果父类没被初始化过,会先初始化父类 被动引用时不会初始化 1、访问静态领域时,只有这个属性在的类会被初始化。比如子类访问父类的静态变量,只有父类被初始化了 2、数组定义类引用,不会初始化 3、引用常量不会
类加载器
负责类的加载。从上到下分为根加载器、扩展加载器、系统加载器、自定义加载器。 类加载器默认采用双亲委派机制加载。也就是加载一个类的时候,先从下到上寻找,如果已经加载过就不加载;如果找到了根加载器却依然没发现加载,就从根加载器开始判断是否能加载,如果能就加载,如果不能就看子类能否加载。 这个机制的作用是为了防止危险代码。比如我自己写了一个java.lang.String,这个类在被加载时,系统会发现,本身就有String类并且已经加载过了,就不会使用这里面的内容。
反射
反射就是可以在程序运行的时候得到类的内部信息,并通过这个去操纵属性和对象。 在一个类被加载后,堆里就出现了该类的Class对象,这个对象包含了类的所有信息,反射就是通过获取这个对象,从而操纵这个类的信息。每个类的Class对象都是独一的。 通过反射可以使得本来是静态语言的Java拥有了一定的动态性,但是降低了性能。
作用
1、在运行时创建对象 2、在运行时判断对象属于哪个类 3、在运行时获取泛型信息 4、在运行时判断某个类是否具有某些成员变量以及方法 5、在运行时调用对象的属性和方法 6、动态代理 7、等等
获取反射对象
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException {
Student s =new Student();
Class c = s.getClass();
Class c1 = Class.forName("Student");
Class c2 = Student.class;
Class c3 = Integer.TYPE;
Class c4 = c.getSuperclass();
}
}
class Person{
}
class Student extends Person{
}
拥有Class对象的类型
public class Test3 {
public static void main(String[] args) {
Class c1 = Object.class;
Class c2 = Runnable.class;
Class c3 = Override.class;
Class c4 = ElementType.class;
Class c5 = String[].class;
Class c6 = int[][].class;
Class c7 = void.class;
Class c8 = Class.class;
Class c9 = Integer.class;
}
}
通过反射对象获取类的信息
public class Test6 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
Class c = Class.forName("User");
c.getName();
c.getSimpleName();
Field[] pFields = c.getFields();
Field[] aFields = c.getDeclaredFields();
c.getField("name");
Method[] pMethod = c.getMethods();
Method[] aMethod = c.getDeclaredMethods();
c.getMethod("setAge", int.class);
Constructor[] pConstructor = c.getConstructors();
Constructor[] aConstructor = c.getDeclaredConstructors();
c.getDeclaredConstructor(String.class,int.class,int.class);
}
}
class User{
private int age;
private int id;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
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 User(int age, int id, String name) {
this.age = age;
this.id = id;
this.name = name;
}
public User() {
}
}
通过反射对象创建对象,执行方法,操作属性
public class Test7 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c = Class.forName("User");
Constructor aConstructor =c.getDeclaredConstructor(int.class,int.class,String.class);
User u1 = (User) aConstructor.newInstance(20,10001,"Jim");
System.out.println(u1);
User u = (User) c.newInstance();
Method aMethod = c.getDeclaredMethod("setName", String.class);
aMethod.invoke(u,"Jerry");
System.out.println(u.getName());
Field aAge = c.getDeclaredField("age");
aAge.setAccessible(true);
aAge.set(u,20);
System.out.println(u.getAge());
}
}
通过反射对象获取泛型信息
public class Test8 {
public static void test1(Map<String,User> map, List<User> list){
System.out.println("test1");
}
public static Map<String,User> test2(){
System.out.println("test2");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Class c = Test8.class;
Method m1 = c.getDeclaredMethod("test1", Map.class, List.class);
Type[] t1 = m1.getGenericParameterTypes();
for (Type type : t1) {
System.out.println("==" + type + "==");
if (type instanceof ParameterizedType){
Type[] t11 = ((ParameterizedType) type).getActualTypeArguments();
for (Type type1 : t11) {
System.out.println(type1);
}
}
}
Method m2= c.getDeclaredMethod("test2",null);
Type t2 = m2.getGenericReturnType();
System.out.println("-----" + t2 + "-----");
if (t2 instanceof ParameterizedType){
Type[] t22 = ((ParameterizedType) t2).getActualTypeArguments();
for (Type type : t22) {
System.out.println(type);
}
}
}
}
通过反射获取注解信息
public class Test9 {
public static void main(String[] args) throws NoSuchFieldException {
Class c = Teacher.class;
Annotation[] a = c.getAnnotations();
for (Annotation annotation : a) {
System.out.println(annotation);
}
ClassInterface f = (ClassInterface) c.getAnnotation(ClassInterface.class);
String value = f.value();
System.out.println(value);
Field field = c.getDeclaredField("age");
FieldInterface fieldInterface = field.getAnnotation(FieldInterface.class);
System.out.println(fieldInterface.length());
System.out.println(fieldInterface.name());
}
}
@ClassInterface("class")
class Teacher{
@FieldInterface(length = 3,name = "age")
private int age;
@FieldInterface(length = 4,name = "name")
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Teacher(int age, String name) {
this.age = age;
this.name = name;
}
public Teacher() {
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassInterface{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldInterface{
int length();
String name();
}
|