注解

image.png
内置注解

image.png
元注解

image.png
package annotation;
import java.lang.annotation.*;
//测试元注解
public class test1 {
public void test(){
}
}
//定义一个注解
//Target表示我们的注解可以用在哪些地方
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//表示我们的注解在什么地方有用
@Retention(value = RetentionPolicy.RUNTIME)
//Documented 表示是否将我们的注解生成在JAVAdoc中
@Documented
//Inhertied子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
自定义注解

注解可以显示赋值,如果没有默认值,我们就必须给注解赋值
- @MyAnnotation(name="shy”)
注解的参数:参数类型+参数名();
- int age() default 0;
- 如果默认值为负一,表示不存在
反射
动态语言
- Object-C,C#,JavaScript,PHP,Python.
静态语言
- Java,C,C++
优点:可实现动态对象的创建和编译,体现出很大的灵活性
缺点:对性能有影响
- Class c1=Class.forName("com.kuang.reflection.User")
- 一个类在内存中只有一个Class对象
Class类

image.png
Class类的常用方法

image.png
package reflection;
import java.lang.reflect.Constructor;
public class test1 {
public static void main(String[] args) throws ClassNotFoundException {
Person person=new Student();
System.out.println("这个人是"+person.name);
//方式1:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式2:通过forname获得
Class c2 = Class.forName("reflection.Student");
System.out.println(c2.hashCode());
//方式3:通过类名.class获得
Class c3=Student.class;
System.out.println(c3.hashCode());
//方式4:基本内置类型包装都有一个TYPE属性
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person(){
}
public Person(String name){
this.name=name;
}
@Override
public String toString(){
return "Person{"+"name='"+name+'\''+'}';
}
}
class Student extends Person{
public Student(){
this.name="学生";
}
}
class Teacher extends Person{
public Teacher(){
this.name="老师";
}
}
拥有class对象的类型

image.png
类的加载

- alt+insert(可以生成构造器)
package reflection;
public class test2 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
class A{
static {
System.out.println("A类静态代码块初始化");
m=300;
}
static int m=100;
public A() {
System.out.println("A类无参构造初始化");
}
}
//m=100
类的初始化
类的主动引用(一定会发生类的初始化)
- 当虚拟机启动,先初始化main方法所在的类
- new一个类的对象
- 调用类的静态成员(除了final常量)和静态方法
- 使用iava.lang.reflect包的方法对类进行反射调用
- 当初始化一个类,如果其父类没有被初始化,则先会初始化它的父类
类的被动引用(不会触发类的初始化)
- 当访问一个静态域时,只有真正声明这个域的类才会被初始化。如:当通过子类引用父类的静态变量,不会导致子类初始化
- 通过数组定义类引用,不会触发此类的初始化
- 引用常量不会触发此类的初始化(常量在链接阶段就存入调用类的常量池中了)
package reflection;
public class test3 {
static {
System.out.println("Main被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
Son son = new Son();
//反射也会产生主动引用
Class.forName("reflection.Son");
}
}
class Father{
static int b=2;
static {
System.out.println("父类被加载");
}
}
class Son extends Father{
static {
System.out.println("子类被加载");
m=300;
}
static int m=100;
static final int M=1;
}
类加载器
-
作用是把类装载进内存
image.png
创建运行时类的对象
获取类的名字
- c1.getName(获得包名加类名)
- c1.getSimpleName(获得类名)
获得类的属性
- c1.getFields(只能找到public属性)
- c1.getDeclareFields()找到全部属性
获得类的方法
- c1.getMethods();
- c1.getDeclaredMethods();
获得制定构造器
- c1.getConstructors();
动态创建对象执行方法
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class test4 {
public static <User> void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//获取Class对象
Class c1 = Class.forName("reflection.User");
//构造一个对象
User user = (User) c1.newInstance();//本质是调用了类的无参构造器
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user2 =(User) constructor.newInstance("shy", 001, 18);
//通过反射构造普通方法
User user3 = (User) c1.newInstance();
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(user3,"shy");//invoke激活
System.out.println(user3.getClass());
}
}
setAccessible
- 启动和禁用访问安全检查开关
反射操作泛型

image.png
获取注解信息
package reflection;
import javax.swing.text.html.parser.TagElement;
import java.lang.annotation.*;
public class test5 {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("reflection.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation:annotations){
System.out.println(annotation);
}
//获得注解Value的值
Tableshy tableshy = (Tableshy)c1.getAnnotation(Tableshy.class);
String value = tableshy.value();
System.out.println(value);
//获得类的指定注解
}
}
@Tableshy("db_student")
class Student2{
@Fieldshy(columnName = "db_id",type = "int",length = 10)
private int id;
@Fieldshy(columnName = "db_age",type = "int",length = 10)
private int age;
@Fieldshy(columnName = "db_name",type = "varchar",length = 3)
private String name;
public Student2(int id,int age,String name) {
this.id = id;
this.age= age;
this.name=name;
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", 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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Tableshy{
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldshy{
String columnName();
String type();
int length();
}
