目录
注解
反射机制 java.Reflection
Class类
类加载的过程
类加载器的作用
通过反射获取运行时类的完整结构
通过反射动态的创建对象
反射操作泛型
反射操作注解
注解
概念:
格式:
注解以 “@注释名” 在代码中存在,还可以添加一些参数值,例如:@Annotation(value=“null”)
内置注解:
@Override 重写的注解
@Deprecated 不推荐程序员使用,可以使用或者有更好的方式
@SuppressWarnings:用来抑制编译时的警告信息
元注解:的作用是负责注解其他注解
@Target:用于描述注解的使用范围(即被描述的注解可以用在什么地方)
@Retention:用于描述注解的生命周期 (runtime>class>source) 默认为runtime
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
自定义注解:使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口
//自定义注解
public class Test{
//注解可以显示赋值,如果没有默认值,我们就必须给注解赋值
@MyAnnotation(name = "HYL",schools = {"清华大学"})
public void test(){}
@MyAnnotation1("HYL")
public void test2(){}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
//注解的参数:参数类型 + 参数名();
String name() default "";
int age() default 0;
int id() default -1;//如果默认值为-1代表不存在,indexof,如果找不到就返回-1
String[] schools() default{"软件工程","清华大学"};
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
String value(); //只有value才能省略
}
反射机制 java.Reflection
动态语言:是一类在运行时可以改变其结构的语言 主要动态语言:Object-C、C#、JavaScript、PHP、Python
静态语言:与动态语言相对的,运行时结构不可改变的语言就是静态语言。如:Java、C、C++。
——java不是动态语言,但Java可以称为“准动态语言”。即Java具有一定的动态性,可以利用反射机制获得类似动态语言的特性。
Java的动态性让编程更加灵活,但是有一定的不安全性。
概述:Reflection(发射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,
并能直接操作任意对象的内部属性及方法。
反射机制提供的功能
-
在运行时判断任意一个对象所属的类
-
在运行时构造任意一个类的对象
-
在运行时判断任意一个类所具有的成员变量和方法
-
在运行时获取泛型信息
-
在运行时调用任意一个对象的成员变量和方法
-
在运行时处理注解
-
生成动态代理
-
.......
反射的优缺点
优点:可以实现动态创建对象和编译,体现出很大的灵活性
缺点:对性能有影响,使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它
满足我们的要求,这类操作总是慢于 直接执行相同的操作。
反射相关的主要API:
-
java.lang.Class : 代表一个类
-
java.lang.reflect.Method : 代表类的方法
-
java.lang.reflect.Field : 代表类的成员变量
-
java.lang.reflect.Constructor : 代表类的构造器
-
.......
package edu.cn.neusoft.project.test;
//什么叫反射
public class Test extends Object{
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的Class对象
Class c1 = Class.forName("edu.cn.neusoft.project.test.User");
System.out.println(c1);
Class c2 = Class.forName("edu.cn.neusoft.project.test.User");
Class c3 = Class.forName("edu.cn.neusoft.project.test.User");
//一个类在内存中只有一个Class对象
//一个类被加载后,类的整个结构都会被封装在Class对象中
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
}
}
//实体类:pojo , entity
class User{
private String name;
private int id;
private int age;
public User() {
}
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
Class类
在Object类中定义了以下的方法,此方法将被所有子类继承
public final Class getClass()
获取Class类的实例
package edu.cn.neusoft.project.test;
//测试Class类的创建方式有哪些
public class Test extends Object{
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:"+person.name);
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式二:forName获得
Class c2 = Class.forName("edu.cn.neusoft.project.test.Student");
System.out.println(c2.hashCode());
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3.hashCode());
//方式四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
//实体类:pojo , entity
class Person{
String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
class Student extends Person{
public Student(){
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "老师";
}
}
哪些类型可以有Class对象:
//所有类型的Class
public class Test extends Object{
public static void main(String[] args) throws ClassNotFoundException {
Class