Java注解与反射07
1. 注解
- 对程序起注释作用
- 可以被其他程序(如编译器)读取
- 约束作用(不符合会报错)
1.1. 内置注解
- @Override:重写方法
- @Deprecated:不推荐使用某方法
- @SupressWarnings:镇压警告
1.2. 元注解
负责注解其他注解(如元注解)
- @Target
- @Retention
- @Document:说明该注解将被包含在javadoc文档中
- @Inherited:说明子类可以继承父类中的该注解
//Target注解限制注解使用的对象,如方法METHOD,类TYPE等
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//Retention注解限制注解使用的范围,SOURCE<CLASS<RUNTIME
@Retention(value = RetentionPolicy.RUNTIME)
//注解属性中的value可以不写
@interface Myannotation{//在类中不能加public,因为类只能存在一个public类
//自定义注解Myannotation
}
1.3. 自定义注解
@interface Myannotation{//自定义注解
String name() default "";
/*定义注解的属性,不是方法
加default表示默认取值*/
String value();//若属性名为value,则可以不加dafault而默认值为""空字符串。
}
2. 反射
Java Reflection:可以使程序在执行期间借助于Reflection API取得任何类的内部信息,并直接操作任意对象的内部属性和方法。
Class:每个类的前缀都是class,这就说明class是一种数据类型,java虚拟机在加载每种class时会实例化一个Class对象(Class本身也是一个类,class Class!),这个Class对象包含了该class(注意,class是数据类型,Class是实例对象!一种class只有一个Class对象)的全部信息,如类名、包名、方法、属性等。那么我们可以利用这个Class对象找到原class的全部属性、方法等,这个过程就叫反射。
Class c1 = Class.forName(“”//类路径,如com.stone.reflection.User);
Object类中定义了public final Class getClass()方法,此方法被所有子类继承,该方法返回值的类型是一个Class类。
一个加载的类只有一个class类。
2.1. 得到class类的几种方式
public class Person{
String name;
public Person(){
}
}
class Student extends Person{
public Student(){
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "老师";
}
}
public class test{
public static void main(String[] args){
Person person = new Student();
}
}
-
Class c1 = Student.class; -
Class c2 = Class.forName("com.stone.reflection.Student");//属性值为包名 -
Class c3 = person.getClass(); -
Class c4 = Integer.TYPE; -
Class c5 = c1.getSuperclass();
3. 类加载内存分析
Java内存分为三个区:
- 堆
- 方法区(特殊的堆)
- 栈
类加载后,生成相应的class对象,链接时会将static中的属性设置为默认值,初始化时
3.1. 类初始化
- 当主类调用子类时,会先初始化main类,再初始化子类的父类,最后初始化子类
- 反射类的class对象时会初始化类
- 调用父类的静态属性不会初始化类
- 实例化引用类的数组时不会初始化类
- 引用类的被static和final同时修饰的常量不会初始化类
3.2. 类加载器
- 系统类加载器:加载用户的jar包
- 扩展类加载器:
- 引导类加载器:加载核心jar包(我们无法调用)
获取类加载器:
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
/*输出结果:
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1b6d3586
null
*/
System.getProperty("java.class.path")//读取类加载路径
3.3. 获取运行时类的结构
-
获取类的名字
-
Class c1 = Class.forName("com.stone.refleciton.User");//括号内时类的路径 System.out.println(c1.getName()); System.out.println(c1.getSimleName());
-
-
获取类的属性
-
Field[] declaredFields = c1.getDeclaredFields();//获取类的全部属性 Field[] field = c1.getFields();//获取类的Public属性 for(Field field : declaredFields){ System.out.println(field); }
-
-
获取类的方法
-
Method[] methods = c1.getDeclaredMethods();//获取类的全部方法 Method[] methods = c1.getMethods();//获取类的public方法
-
3.4. 动态创建对象执行方法
Class c1 = Class.forName("com.stone.reflecttion.User");
-
通过User的无参构造器创建User类的对象
-
User user = (User)c1.newInstance();//newInstance用于创建c1的实例并强制转换为User类型
-
-
通过有参构造器进行实例化
-
Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class); User user2 = (User)constructor.newInstance("stone",001,18);//通过User类的有参构造器进行实例化对象
-
-
获取User类的方法
-
User user3 = (User)c1.newInstance(); Method setName = c1.getDeclaredMethod("setName",String name); setName.invoke(user3,"stone"); System.out.println(user3.getName());
-
-
获取User类的属性
-
User user4 = (User)c1.Instance(); Field name = c1.getDeclaredField("name"); name.setAccessible(true);//关闭程序的安全检测,使得可以读取类的私有属性 name.set(user4,"stone");
-
-
当反射较多时,调用setAccessible()关闭Java语言安全检测可以提高运行效率
4. 获取注解信息
@Target(ElementType.FIELD)//注解作用类型为属性
@Retention(RetentionPolicy.RUNTIME)//注解作用范围为程序运行时
@interface Fielstone{//自定义属性注解
String columnName();
String type();
int length();
}
@Target(ElementType.TYPE)//注解作用类型为类
@Retention(RetentionPolicy.RUNTIME)//注解作用范围为程序运行时
@interface Tablestone{//自定义类注解
String value();
}
@Tablestone("db_stone")
class Student2{
@Fieldstone(columnName = "db_id",type = "int",length = 10)
private int id;
@Fieldstone(columnName = "db_age",type = "int",length = 10)
private int age;
@Fieldstone(columnName = "db_name",type = "varchar",length = 3)
private String name;
public Student2(){
}
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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Test{
public void static main(String[] args){
Class c1 = Class.forName("com.stone.reflecion.Student2")
Tablestone tablestone = (Tablestone)c1.getAnnotation(Tablestone.class);//获取Tablestone注解的class类,并实例化
String value = tablestone.getValue();取得Tablestone类的值
System.out.println(value);
/*输出结果:
db_stone
*/
}
}
浙公网安备 33010602011771号