注解Annotation
@注释名(参数值) 。注解只是起一个注释作用,单独使用对程序无影响。
内置注解:
- @Override 重写方法声明
- @Deprecated 废弃方法
元注解
负责注解其他注解。
- @Target:用户描述注解使用范围。
- @Rentention:表示需要在什么级别保存该注释。(SOURCE<CLASS<RUNTIME)
- @Document:说明该注解将被包含在javadoc中。
- @Inherited:说明子类可以继承父类中的该注解。
//表示注解使用目标
@Target(value = {ElementType.METHOD,ElementType.TYPE})
//表示注解在什么地方有效
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyAnnotation{
}
自定义注解
public class Test03 {
@MyAnnotation2(age = 18)
public void test(){
}
@MyAnnotation3("只有value才能不写value=")
public void test2(){}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
String name() default "";
int age() default 0;
int id() default -1;//默认值-1,则表示不存在
String[] schools() default {"北京","清华大学"};
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{
String value();
}
反射机制Reflection
动态语言: 运行时可以改变结构语言。
Java不是动态语言,但可以通过反射获得类似动态语言特性。
//通过反射获取类的class对象
Class<?> c1 = Class.forName("com.yao.reflection.User");
Class<?> c2 = Class.forName("com.yao.reflection.User");
Class<?> c3 = Class.forName("com.yao.reflection.User");
System.out.println(c1);//class com.yao.reflection.User
//一个类在内存中只有一个class对象
System.out.println(c1.hashCode());//1476011703
System.out.println(c2.hashCode());//1476011703
System.out.println(c3.hashCode());//1476011703
Class类
1个Class对象对应 .class文件。
通过Class的可以获得类的对象等。
Person person = new Student();
System.out.println(person.name);
//获得Class对象
//1.通过对象获得
Class c1 = person.getClass();
//2.forname获得
Class c2 = Class.forName("com.yao.reflection.Student");
//3.类。class获得
Class c3 = Student.class;
System.out.println(c3);
System.out.println(c1.hashCode()==c2.hashCode());//true
System.out.println(c3.hashCode()==c2.hashCode());//true
//4.基本内置类型包装类
Class c4 = Integer.TYPE;
System.out.println(c4);//int
//获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
绝大多类型都有Class对象。
通过Class获得类对象。
Class<?> cl = Class.forName("com.yao.reflection.User");
//获得包名+类名
System.out.println(cl.getName());
//获得类属性
System.out.println("-----");
//只能获得public属性
Field[] fields = cl.getFields();
//获得全部属性
fields = cl.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
//获得指定属性值
Field name = cl.getDeclaredField("name");
System.out.println(name);
//获得类方法
System.out.println("=========");
//public
Method[] methods = cl.getMethods();
//所有方法
Method[] declaredMethods = cl.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
//获得指定方法
Method getName = cl.getMethod("getName", null);
System.out.println(getName);
//获得构造器
Constructor<?>[] constructors = cl.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
动态创建对象执行方法
Class<?> c1 = Class.forName("com.yao.reflection.User");
//该方法需要无参构造器
Object o = c1.newInstance();
System.out.println(o);
//通过构造器创建对象
Constructor<?> constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
Object o1 = constructor.newInstance("对象", 12, 12);
System.out.println(o1);//User{name='对象', age=12, id=12}
//通过反射调用普通方法
Method setName = c1.getDeclaredMethod("setName", String.class);
setName.invoke(o,"对象2");
System.out.println(o);//User{name='对象2', age=0, id=0}
//通过反射操作属性
Field age = c1.getDeclaredField("age");
//操作私有属性,需要关闭检测
age.setAccessible(true);
age.set(o,18);
System.out.println(o);//User{name='对象2', age=18, id=0}
反射方式相比普通方式性能低很多,关闭检查后能减少一点性能损失。
反射操作泛型
Method test01 = Test07.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = test01.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("#"+genericParameterType);
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
Method test02 = Test07.class.getMethod("test02");
Type genericParameterType = test02.getGenericReturnType();
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
反射操作注解
ORM对象关系映射。
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class<?> c1 = Class.forName("com.yao.reflection.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解value值
TableYao tableYao = c1.getAnnotation(TableYao.class);
System.out.println(tableYao.value());//db_student
//获得类指定注解
Field name = c1.getDeclaredField("name");
FieldYao annotation = name.getAnnotation(FieldYao.class);
System.out.println(annotation.columnName());//db_name
System.out.println(annotation.length());//10
System.out.println(annotation.type());//varchar
}
}
@TableYao("db_student")
class Student2{
@FieldYao(columnName = "db_id",type = "int",length = 10)
private int id;
@FieldYao(columnName = "db_age",type = "int",length = 10)
private int age;
@FieldYao(columnName = "db_name",type = "varchar",length = 10)
private String name;
public Student2() {
}
public Student2(int id, int age, String name) {
this.id = id;
this.age = age;
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;
}
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 + '\'' +
'}';
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableYao{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldYao{
String columnName();
String type();
int length();
}