java注解和反射 --狂神说
程序员文章站
2022-03-09 08:03:12
注解Annotation内置注解@override:定义重写声明@Deprecated:表示不鼓励使用@SuppressWarnings:抑制警告信息使用需要参数 参数已经定义好了 选择使用即可1.@SuppressWarnings(“all”)2.@SuppressWarnings(“unchecked”)3.@SuppressWarnings(value={“unchecked”,“deprecation”})package First;import java.util.Arra...
注解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();
}
}
元注解 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{}
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;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", 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 = "教师";
}
}
这个人是:学生
460141958
460141958
460141958
int
class Reflection.Person
有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
460141958
460141958
加载类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;
}
类加载器
package Reflection;
public class Demo06 {
public static void main(String[] args) throws ClassNotFoundException {
//获得系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
//获得系统类加载器的父类-->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);
//获得扩展类加载器的父类-->根加载器(c/c++)无法直接获得
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);
//测试当前类由哪个加载器产生
ClassLoader classLoader = Class.forName("Reflection.Demo06").getClassLoader();
System.out.println(classLoader);
//测试jdk类
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
//如何获得系统类加载器的加载路径
System.out.println(System.getProperty("java.class.path"));
/*
D:\Java\jdk1.8.0_261\jre\lib\charsets.jar;
D:\Java\jdk1.8.0_261\jre\lib\deploy.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\access-bridge-64.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\cldrdata.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\dnsns.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\jaccess.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\jfxrt.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\localedata.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\nashorn.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\sunec.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\sunjce_provider.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\sunmscapi.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\sunpkcs11.jar;
D:\Java\jdk1.8.0_261\jre\lib\ext\zipfs.jar;
D:\Java\jdk1.8.0_261\jre\lib\javaws.jar;
D:\Java\jdk1.8.0_261\jre\lib\jce.jar;
D:\Java\jdk1.8.0_261\jre\lib\jfr.jar;
D:\Java\jdk1.8.0_261\jre\lib\jfxswt.jar;
D:\Java\jdk1.8.0_261\jre\lib\jsse.jar;
D:\Java\jdk1.8.0_261\jre\lib\management-agent.jar;
D:\Java\jdk1.8.0_261\jre\lib\plugin.jar;
D:\Java\jdk1.8.0_261\jre\lib\resources.jar;
D:\Java\jdk1.8.0_261\jre\lib\rt.jar;
D:\Program Files\IDEA\IntelliJ IDEA Community Edition 2020.2.2\Annotation\out\production\Annotation;
D:\Program Files\IDEA\IntelliJ IDEA Community Edition 2020.2.2\lib\idea_rt.jar
*/
//双亲委派机制
//当你定义的与根加载器中有类重复 为保证安全 仍使用根加载器中的类
}
}
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$ExtClassLoader@1b6d3586
null
sun.misc.Launcher$AppClassLoader@18b4aac2
null
双亲委派机制: 当某个类加载器需要加载某个.class
文件时,它首先把这个任务委托给他的上级类加载器,递归这个操作,如果上级的类加载器没有加载,自己才会去加载这个类。
获取类的运行时状态
package Reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Demo07 {
public static void main(String[] args) throws Exception {
Class c1 = Class.forName("Reflection.User");
//User user = new User(); c1 =User.Class();
System.out.println(c1.getName());//获取包名加类名
System.out.println(c1.getSimpleName());//获取类名
//获取属性
Field[] fields = c1.getFields();//获得public属性
for (Field field:fields) {
System.out.println(field);
}
fields = c1.getDeclaredFields();//获得全部属性
for (Field field:fields) {
System.out.println(field);
}
//获得指定属性
System.out.println(c1.getDeclaredField("name"));
//获取方法
Method[] methods = c1.getMethods();//获得当前类与父类的public方法
for (Method method : methods) {
System.out.println("正常的"+method);
}
methods =c1.getDeclaredMethods();//获得当前类的所有方法
for (Method method : methods) {
System.out.println("getDeclaredMethods"+method);
}
//获得指定方法
//加参数 处理重载
System.out.println(c1.getMethod("getId",null));
System.out.println(c1.getMethod("setName", String.class));//含参数需指定
//获取构造器
Constructor[] constructors = c1.getConstructors();//获得public构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();//获得全部构造器
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获得指定构造器
System.out.println(c1.getConstructor(String.class,int.class,int.class));
}
}
Reflection.User
User
java.lang.String Reflection.User.name
int Reflection.User.age
int Reflection.User.id
java.lang.String Reflection.User.name
正常的public java.lang.String Reflection.User.toString()
正常的public java.lang.String Reflection.User.getName()
正常的public int Reflection.User.getId()
正常的public void Reflection.User.setName(java.lang.String)
正常的public int Reflection.User.getAge()
正常的public void Reflection.User.setId(int)
正常的public void Reflection.User.setAge(int)
正常的public final void java.lang.Object.wait() throws java.lang.InterruptedException
正常的public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
正常的public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
正常的public boolean java.lang.Object.equals(java.lang.Object)
正常的public native int java.lang.Object.hashCode()
正常的public final native java.lang.Class java.lang.Object.getClass()
正常的public final native void java.lang.Object.notify()
正常的public final native void java.lang.Object.notifyAll()
getDeclaredMethodspublic java.lang.String Reflection.User.toString()
getDeclaredMethodspublic java.lang.String Reflection.User.getName()
getDeclaredMethodspublic int Reflection.User.getId()
getDeclaredMethodspublic void Reflection.User.setName(java.lang.String)
getDeclaredMethodspublic int Reflection.User.getAge()
getDeclaredMethodspublic void Reflection.User.setId(int)
getDeclaredMethodspublic void Reflection.User.setAge(int)
public int Reflection.User.getId()
public void Reflection.User.setName(java.lang.String)
public Reflection.User()
public Reflection.User(java.lang.String,int,int)
public Reflection.User()
public Reflection.User(java.lang.String,int,int)
public Reflection.User(java.lang.String,int,int)
动态创建对象
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
==========
小小
性能检测
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.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Demo10 {
public void test01(Map<String ,User> map,List<String> list){
System.out.println("这不重要");
}
public Map<String ,User> test02(){
System.out.println("这不重要");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Demo10.class.getDeclaredMethod("test01",Map.class,List.class);
Type[] genericParameterTypes = method.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);
}
}
}
System.out.println("=========================");
method = Demo10.class.getDeclaredMethod("test02");
Type genericReturnType = method.getGenericReturnType();
if(genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
java.util.Map<java.lang.String, Reflection.User>
class java.lang.String
class Reflection.User
java.util.List<java.lang.String>
class java.lang.String
=========================
class java.lang.String
class Reflection.User
通过反射获得注解
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() {
}
@Override
public String toString() {
return "Student2{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
@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
本文地址:https://blog.csdn.net/qq_43203246/article/details/109611218