注解Annotation
内置注解
@override:定义重写声明
@Deprecated:表示不鼓励使用
@SuppressWarnings:抑制警告信息
使用需要参数 参数已经定义好了 选择使用即可
1.@SuppressWarnings(“all”)
2.@SuppressWarnings(“unchecked”)
3.@SuppressWarnings(value={“unchecked”,“deprecation”})
package First;
import java.util.ArrayList;
import java.util.List;
public class Demo01 extends Object{
//@Override 重写的注解
@Override
public String toString() {
return "Demo01{}";
}
//@Deprecated 不推荐程序员使用 但是可以使用 一般有更好的方法
@Deprecated
public static void test(){
System.out.println("Deprecated");
}
@SuppressWarnings("all") //下方未使用的警告不再提示
public static void test02(){
List list = new ArrayList();
}
public static void main(String[] args) {
test();
}
}
12345678910111213141516171819202122232425
元注解 meta-annotation
自定义注解 @interface
package First;
import java.lang.annotation.*;
//@MyAnnotation 定义注解目标为方法 故不可以使用
public class Test02 {
@MyAnnotation//定义注解目标为方法 故可以使用
public void test(){
}
}
//@Target 表示我们的注解可以用在那些地方 值为ElementType
@Target(value = ElementType.METHOD)
//@Retention 表示我们的注解可以用在哪些地方
//runtime运行时>class>sourcejava
@Retention(value = RetentionPolicy.RUNTIME)
//@Documented 表示是否我们的注解生成在JAVAdoc中
@Documented
@Inherited //表示子类可以继承注解
@interface MyAnnotation{}
123456789101112131415161718192021222324
package First;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test03 {
@MyAnnotation03("当场注解")
@MyAnnotation02(age = 10,name = "alin")//参数顺序可以调换 必许带参数名
public void test03(){
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation02{
//参数定义 参数类型 参数名()
String name() default "";//default 进行默认赋值
int age() default 0;
int id() default -1;//表示不存在
String[] students() default {"青岛大学","南京邮电大学" };
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation03{
String value();//一个参数时 最好命名为value 命名为value时 在使用此注解时可以不加value
}
反射Reflection
package Reflection;
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的Class类型
Class c1 = Class.forName("Reflection.User");
Class c2 = Class.forName("Reflection.User");
Class c3 = Class.forName("Reflection.User");
//一个类只有一个Class对象 故c1 c2 c3 hashcode相同
//一个类被加载之后 类的整个结构都会被封装在Class对象中
System.out.println(c1.hashCode());
System.out.println(c1.hashCode());
System.out.println(c1.hashCode());
}
}
//实体类 pojo entity
class User{
String name;
int age;
int id;
public User() {
}
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
}
Class类
获得class的方法
package Reflection;
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:"+person.name);
//通过对象获得class
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//通过类获得class
Class c2 = Student.class;
System.out.println(c2.hashCode());
//通过forname获得class
Class c3 = Class.forName("Reflection.Student");
System.out.println(c3.hashCode());
//通过内置函数的包装类获得class
Class c4 = Integer.TYPE;
System.out.println(c4);
//获得父类的class
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
}
class Student extends Person{
public Student() {
this.name="学生";
}
}
class Teacher extends Person{
public Teacher() {
this.name = "教师";
}
}
有Class对象
package Reflection;
import java.net.InterfaceAddress;
import java.util.Enumeration;
//拥有class对象的类型
public class Demo03 {
public static void main(String[] args) {
Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = String[].class;
Class c4 = int[][].class;
Class c5 = Enumeration.class;
Class c6 = Integer.class;
Class c7 = Override.class;
Class c8 = Void.class;
Class c9 = void.class;
Class c10 = Class.class;
System.out.println(c1 );
System.out.println(c2 );
System.out.println(c3 );
System.out.println(c4 );
System.out.println(c5 );
System.out.println(c6 );
System.out.println(c7 );
System.out.println(c8 );
System.out.println(c9 );
System.out.println(c10);
//当类型和维数相同时只有一个class对象
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass().hashCode());
System.out.println(b.getClass().hashCode());
}
}
输出:
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.util.Enumeration
class java.lang.Integer
interface java.lang.Override
class java.lang.Void
void
class java.lang.Class
加载类class
package Reflection;
public class Demo04 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);
}
}
/*
1.加载到内存,会产生一个类对应Class对象在堆区
2.链接,在栈中产生 main m=0;
3.初始化
<clinit>{
System.out.println("A类静态代码块初始化");
m=300;
m=100; 静态 按顺序执行的 若把 int m =100 ;放上面 则为300;
}
*/
class A{
static {
System.out.println("A类静态代码块初始化");
m=300;
}
/*
m=300;
m=100; 覆盖上方300
*/
static int m =100;
public A() {
System.out.println("A类的无参构造器");
}
}
输出:
A类静态代码块初始化
A类的无参构造器
100
类的初始化
package Reflection;
public class Demo05 {
static {
System.out.println("Main类被调用了");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.创建对象 若父类没初始化 先初始化父类
//Son son = new Son();
/*
Main类被调用了
父类被加载
子类被加载了
100
*/
//2.通过反射
//Class c1 = Class.forName("Reflection.Son");//Main类被调用 父类被加载 子类被加载了
//3.调用静态
//System.out.println(Son.m);//Main类被调用了 父类被加载 子类被加载了 200
//被动引用
//子类引用父类静态变量
//System.out.println(Son.b);//Main类被调用了 父类被加载 100
//数组定义类引用,不触发初始化
//Son[] a1 = new Son[5]; Main类被调用了
//引用常量,不触发初始化
//System.out.println(Son.M); Main类被调用了 1
}
}
class Father{
static {
System.out.println("父类被加载");
//int b=10;
}
static int b =100;
}
class Son extends Father{
static {
System.out.println("子类被加载了");
m=300;
}
static int m=200;
static final int M=1;
}
类加载器
双亲委派机制: 当某个类加载器需要加载某个.class
文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。
动态创建对象
invoke setAccessible
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo08 {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("Reflection.User");
//反射得到对象
//User user = (User) c1.newInstance();//调用无参构造器 new一个对象 高版本此方法已过时 使用c1.getDeclaredConstructor().newInstance()
//System.out.println(user);
//使用构造器
//Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
//User user1=(User)constructor.newInstance("小明",18,001);
//System.out.println(user1);
//反射调用普通方法
User user= (User) c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getMethod("setName",String.class);
//invoke 激活 (对象,"方法的值")
setName.invoke(user,"ck");
System.out.println(user.getName());
//通过反射操作属性
System.out.println("==========");
User user1=(User)c1.newInstance();
Field name = c1.getDeclaredField("name");
name.setAccessible(true);//关闭安全检测 对私有属性可以操作
name.set(user1,"小小");
System.out.println(user1.getName());
}
}
ck
==========
小小
123456789101112131415161718192021222324252627282930313233343536
性能检测
package Reflection;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Demo09 {
//普通调用
public static void test01(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
user.getName();
}
long endTime =System.currentTimeMillis();
System.out.println("普通调用10亿次耗费"+(endTime-startTime)+"ms");
}
//反射调用
public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
}
long endTime =System.currentTimeMillis();
System.out.println("反射调用10亿次耗费"+(endTime-startTime)+"ms");
}
//关闭安全检测
public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
User user = new User();
Class c1 = user.getClass();
Method getName = c1.getDeclaredMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(user,null);
}
long endTime =System.currentTimeMillis();
System.out.println("关闭安全检测后反射调用10亿次耗费"+(endTime-startTime)+"ms");
}
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
test01();
test02();
test03();
}
}
普通调用10亿次耗费4ms
反射调用10亿次耗费2063ms
关闭安全检测后反射调用10亿次耗费1265ms
可以看出 反射的方式调用 耗时较久
通过反射获得注解
package Reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Demo11 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("Reflection.Student2");
//获得类的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解的值
Typekang typekang =(Typekang) c1.getAnnotation(Typekang.class);
String value =typekang.value();
System.out.println(value);
//获得指定注解的值
Field field = c1.getDeclaredField("name");
Fieldkang fieldkang = field.getAnnotation(Fieldkang.class);
System.out.println(fieldkang.columname());
System.out.println(fieldkang.type());
System.out.println(fieldkang.length());
}
}
@Typekang("db_Student")
class Student2{
@Fieldkang(columname = "db_name",type = "varchar",length = 10)
private String name;
@Fieldkang(columname = "db_age",type = "int",length = 10)
private int age;
@Fieldkang(columname = "db_id",type = "int",length = 10)
private int id;
public Student2(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public Student2() {
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Typekang{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fieldkang{
String columname();
String type();
int length();
}
@Reflection.Typekang(value=db_Student)
db_Student
db_name
varchar
10