注解
注解的简介
-
什么是注解
是对数据的说明和约束,解析给计算机看
内置注解
@Target(value) //定义注解使用范围 方法 属性 类
@Retension(value) //定义注解什么时候使用
@Documented //可以生成文档的
@Inherited //可以继承的
public class test01 {
public void test(){}
@Override //重写注解 作用:写错报错提示
public void toString(){}
public static void main(String[] args){
@SuppressWarnings //压制警告 编译警告没有提示 建议不用
int a=0;
}
}
自定义注解
@Target(ElementType.TYPE)//定义注解使用范围为类
@Retension(RetensionPolicy.RUNTIME)//注解运行时使用
//@interface 定义注解
@interface Test {
//注解参数
String value();
int age();
int id();
}
@Test(value="黄忠",age=12,id=1)
public class Test02 {}
反射
package com.lusheng.demo01;
//什么叫反射
public class TestReflection {
public static void main(String[] args)throws ClassNotFoundException{
//通过反射可以获取类对象
Class cs = Class.forName("com.lusheng.demo01.Person");
Class cs1 = Class.forName("com.lusheng.demo01.Person");
Class cs2 = Class.forName("com.lusheng.demo01.Person");
System.out.println(cs.getName());//类名
//一个类只有一个类对象
//一个类加载后,类的结构封装在类对象中
System.out.println(cs.hashCode());
System.out.println(cs1.hashCode());
System.out.println(cs2.hashCode());
}
}
class Person {
private int age;
private String name;
private int id;
private String address;
public Person(int age ,int id ,String name, String address){
this.age = age;
this.id = id;
this.name = name;
this.address = address;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
", id=" + id +
", address='" + address + '\'' +
'}';
}
}
CLASS类
-
Class类本身也是一个类
-
Class对象只能是被系统生成
-
一个加载的类在JVM中只能有一个实列
-
一个类对象对应的是Class字节文件
-
通过Class可以获取类中所有被加载的信息
-
Class与反射
获取CLASS对象的方式
public class Test02 {
public static void main(String[] args)throws ClassNotFoundException{
Person stu = new Student();
//方式1:forName("完整的包路径+类名") 需要throws 异常
Class cs1 = Class.forName("完整的包路径+类名");
//方式2:对象.getClass();
Class cs2 = stu.getClass();
//方式3:类.class
Class cs3 = Person.class;
//方式4:内置类.TYPE
Class cs4 = Integer.TYPE;
//子类Class对象获取父类Class对象
Class cs5 = cs1.getSuperClass();
}
}
class Person {}
class Student extends Person {}
所有数据类型的Class对象
public class Test03 {
public static void main(String[] args){
Class cs1 = Object.class; //Object
Class cs2 = Boolean[].class;// 一维数组
Class cs3 = int[][].class; //二维数组
Class cs4 = Enum.class; //枚举
Class cs5 = void.class;//void
Class cs6 = Comparable.class; //接口
Class cs7 = Override.class; //注解
Class cs8 = Class.class; //Class
Class cs9 = int.class; //基本数据类型
System.out.println(cs2);
System.out.println(cs3);
System.out.println(cs4);
System.out.println(cs5);
System.out.println(cs6);
System.out.println(cs7);
System.out.println(cs8);
System.out.println(cs9);
System.out.println(cs1);
//统一维度统一类型 只有一个Class对象
int[] a = new int[30];
int[] b = new int[100];
System.out.println(a.getClass().hashCode()==b.getClass().hashCode());
}
}
类加载内存分析
1.类文件读入内存,创建Class对象 类的加载
2.二进制数组合并JRE中 类的连接 验证 准备 解析
3.类的初始化 client()
public class Test03 {
public static void main(String[] args) {
new A();
System.out.println(A.b);
}
}
class A {
static int b;
static {
System.out.println("静态代码块");
b = 300;
}
static {
b = 100;
}
public A(){
System.out.println("构造初始化");
}
类初始化分析
public class Test04 {
static {
System.out.println("+++Main");
}
public static void main(String[] args) throws ClassNotFoundException{
//Father s = new Son();
//System.out.println(Son.a);
//Class c1 = Class.forName("com.lusheng.demo01.Son");
//
//System.out.println(Son.b);
Son[] son = new Son[10];
}
}
class Father {
static {
System.out.println("father静态代码块");
}
static int a = 100;
}
class Son extends Father {
static {
System.out.println("son静态代码块");
}
static final int b = 10;
}
类加载器
-
作用:字节码文件加载到内存并将静态数据转换为方法区数据结构 推中生 成一个类对象文件
-
类缓存:加载后被缓存
-
加载器的分类
- Bootstap ClassLoader C++语言编写 负责加载核心库 无法直接获得
- Extension ClassLoader 扩展类加载器 负责加载 jre/lib/ext下的Jar包
- System ClassLoader 系统类加载器 负责加载类路径下的类或Jar包 常用加载器
public class Test05 { public static void main(String[] args) throws ClassNotFoundException{ //系统类加载器 System Classloader ClassLoader classLoader = ClassLoader.getSystemClassLoader(); System.out.println(classLoader); //系统加载器父类加载器---->Extension Classloader ClassLoader parent = classLoader.getParent(); System.out.println(parent); //扩展类加载器的父类加载器----->Bootstap Classloader parent = parent.getParent(); System.out.println(parent); //双亲委派机制--->java.lang.String 往上找 //测试当前类被哪个加载器加载 classLoader = Class.forName("com.lusheng.demo01.Test05").getClassLoader(); System.out.println(classLoader); //测试内置类的加载器 classLoader = Object.class.getClassLoader(); System.out.println(classLoader); //获取系统加载器可以加载的路径 System.out.println(System.getProperty("java.class.path")); } }
获取类信息
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Test06 { public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class c1 = Class.forName("java.lang.String"); //获取类名 System.out.println(c1.getName()); System.out.println(c1.getSimpleName()); //获取类属性 Field[] fields = c1.getFields();//获取public 属性 for (Field field : fields) { System.out.println(field); } Field[] declaredFields = c1.getDeclaredFields();//获取所有包括private 属性 for (Field declaredField : declaredFields) { System.out.println(declaredField); } //获取指定属性 Field serialVersionUID = c1.getDeclaredField("serialVersionUID"); System.out.println(serialVersionUID); //获取方法 Method[] methods = c1.getMethods();//public方法 包括父类 for (Method method : methods) { System.out.println(method); } Method[] declaredMethods = c1.getDeclaredMethods();//获取该类中所有方法 for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); } //获取指定方法 Method toString = c1.getMethod("toString", null); Method repeat = c1.getMethod("repeat", int.class); //获取构造方法 Constructor[] constructors = c1.getConstructors();//public 构造器 for (Constructor constructor : constructors) { System.out.println(constructor); } Constructor[] declaredConstructors = c1.getDeclaredConstructors();//所有构造方法 for (Constructor declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } //获取指定构造方法 Constructor constructor = c1.getConstructor(byte[].class, int.class); System.out.println(constructor); } }
反射创建对象
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test07 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//通过反射创建对象
//1.直接使用newInstance()创建对象 必须是无参数构造 二必须权限够
Class c1 = Class.forName("com.lusheng.demo01.Persons");
Persons per = (Persons)c1.newInstance();
System.out.println(per);
//使用构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(int.class, String.class);
per = (Persons)constructor.newInstance(12,"煌中");
System.out.println(per);
//对象操作方法
Persons per = (Persons)c1.newInstance();
Method setName = c1.getMethod("setName", String.class);
//invoke 激活:通过反射获取方法进行激活使用 差数为对象 和 方法参数
setName.invoke(per,"那红");
System.out.println(per.getName());
//操作属性
//通过反射无法设置私有属性 必须使用setAccessible(true)关闭安全检查 默认false开启
Field name = c1.getDeclaredField("name");
name.setAccessible(true);
name.set(per,"哈哈");
System.out.println(per.getName());
}
}
//分析性能问题
public class Test08 {
public static void test1(){
long startTime = System.currentTimeMillis();
Persons per = new Persons();
for (int i = 0; i < 1000000000; i++) {
per.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方法需要的时间:"+(endTime-startTime));
}
public static void test2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Persons per = new Persons();
Class aClass = per.getClass();
Method getName = aClass.getDeclaredMethod("getName");
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(per,null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭安全检查前:"+(endTime-startTime));
}
public static void test3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Persons per = new Persons();
Class aClass = per.getClass();
Method getName = aClass.getDeclaredMethod("getName");
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(per,null);
}
long endTime = System.currentTimeMillis();
System.out.println("关闭安全检查后:"+(endTime-startTime));
}
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
test1();
test2();
test3();
}
}
//总结:关闭安全检查比不关闭安全检查性能高
反射操作泛型
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 Test09 {
public void test(Map<String,Persons> map, List<Integer> b){
}
public Map<String,Persons> test1(){
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
//获取泛型参数信息
Test09 ts = new Test09();
Class c1 = ts.getClass();
Method test = c1.getDeclaredMethod("test", Map.class, List.class);
Type[] genericParameterTypes = test.getGenericParameterTypes();//Generic泛型
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 test1 = c1.getDeclaredMethod("test1", null);
Type genericReturnType = test1.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
反射操作注解
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test10 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.lusheng.demo01.Students");
//获取注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取注解值
Annotation annotation = c1.getAnnotation(TableStu.class);
TableStu tableStu = (TableStu) annotation;
String value = tableStu.value();
System.out.println(value);
//属性注解
Field name = c1.getDeclaredField("name");
Fas annotation1 = name.getAnnotation(Fas.class);
System.out.println(annotation1.cu());
System.out.println(annotation1.type());
System.out.println(annotation1.length());
}
}
@TableStu("信息表")
class Students {
@Fas(cu="db_db",type="String",length=10)
private String name;
@Fas(cu="db_db",type="int",length=10)
private int age;
@Fas(cu="db_db",type="int",length=10)
private int id;
public Students(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 "Students{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableStu {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Fas {
String cu();
String type();
int length();
}