一、注解
1.1 注解入门
Annonation(jdk5开始引入)的作用:不是程序本身,可以对程序作出解释,可以被其它程序读取,并且可以起到检查和约束的作用。
格式:@xxx 可以添加参数 value=xxx
元注解:负责注解其它注解。
4个标准的meta-annonation类型:@Target、@Retention、@Documented、@Inherited
@Target:表示我们的注解可以用在哪些地方
@Retention:表示我们的注解在什么地方还有效(RUNTIME>CLASS>SOURCES)
@Documented:表示是否将我们的注解生成在javadoc中
@Inherited:子类可以继承父类的注解
自定义注解:@interface,自动继承了java.lang.annotation.Annotation接口
格式:public @interface 注解名{定义内容}
注解的参数:参数类型 + 参数名 + ()
如果只有一个值的话,可以命名为value(),这样上面调用到注解的时候可以不用写参数名
//自定义注解
public class Test01 {
@MyAnnotation(name = "你好",schools = "北大")
public void test02(){
}
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String name() default "";
int age() default 0;
int id() default -1;
String[] schools();
}
二、反射
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。
Class c = Class.forName("java.lang.String");
Class类
Class类常用方法
public class Test01 extends Object {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
//通过反射来获取类的class对象
Class c1 = Class.forName("com.java.reflection.User");
Method m1 = c1.getMethod("getAge");
System.out.println(c1);//class com.java.reflection.User
System.out.println(m1);//public int com.java.reflection.User.getAge()
//一个类在内存中只有一个class对象,其hashCode相同
//一个类被加载后,类的整个结构都会被封装在class对象中
Class c2 = Class.forName("com.java.reflection.User");
Class c3 = Class.forName("com.java.reflection.User");
System.out.println(c2.hashCode());//21685669
System.out.println(c3.hashCode());//21685669
}
}
//实体类
class User{
private int id;
private String name;
private int age;
public User() {
}
public User(String name, int id, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Test04 {
public static void main(String[] args) {
A a = new A();
System.out.println(A.m);//A类静态代码块初始化 A类的无参构造初始化 100
/*
1.加载到内存,会产生一个类对应class对象
2.链接,链接结束后 m=0
3.初始化(static代码会被合并)
<clinit>(){
System.out.println("A类静态代码块初始化");
m = 300;
m = 100;
}
*/
}
}
class A{
static{
System.out.println("A类静态代码块初始化");
m = 300;
}
static int m = 100;
public A() {
System.out.println("A类的无参构造初始化");
}
}
类加载内存分析
类的加载过程
类的加载与ClassLoader的理解
什么时候发生类的初始化
package com.java.reflection;
public class Test05 {
static {
System.out.println("Main类被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
//1.主动引用
Son son = new Son();
//2.反射也会产生主动引用
Class.forName("com.java.reflection.Son");
/*
Class c1 = Son.class;
*/
//不会产生类的引用的方法
System.out.println(Son.b);//调用父类中的值,没有引起子类的初始化
Son[] array = new Son[5];//数组定义类引用不会引起类的初始化
System.out.println(Son.M);//常量在链接阶段就存入了调用类的常量池中了
}
}
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;
}
类加载器的作用
package com.java.reflection;
public class Test06 {
public static void main(String[] args) throws ClassNotFoundException {
//获取系统类的加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//获取系统类加载器的父类加载器-->扩展类加载器
ClassLoader parent = systemClassLoader.getParent();
System.out.println(parent);//sun.misc.Launcher$ExtClassLoader@14ae5a5
//获取扩展类的父类加载器-->根加载器(c++)
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);//null
//测试当前类是哪个加载器加载的
ClassLoader classLoader = Class.forName("com.java.reflection.Test06").getClassLoader();
System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//测试jdk内部类是哪个加载器加载的
classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);//null
}
}
Class对象之后
调用指定方法所需注意
setAccessible()
public class Test08 {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获得class对象
Class c1 = Class.forName("com.java.reflection.User");
//构造一个对象
User user = (User)c1.newInstance();
System.out.println(user);
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user2 = (User)constructor.newInstance("张三", 1, 18);
System.out.println(user2);
//通过反射调用普通方法
User user3 = (User)c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getMethod("setName", String.class);
//invoke : 激活的意思
//(对象,“方法的值")
setName.invoke(user3,"SchParis");
System.out.println(user3.getName());
//通过反射操作属性
User user4 = (User)c1.newInstance();
Field name = c1.getDeclaredField("name");
//不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
name.setAccessible(true);
name.set(user4, "小李子");
System.out.println(user4.getName());
}
}
反射操作泛型
//通过反射获取泛型
public class Test10 {
public void test01(Map<String, User> map, List<User> list){
System.out.println("test01");
}
public Map<String, User> test02(){
System.out.println("test02");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method01 = Test10.class.getMethod("test01", Map.class, List.class);
Type[] genericParameterTypes = method01.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 method02 = Test10.class.getMethod("test02", null);
Type genericReturnType = method02.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
通过反射操作注解
package com.java.reflection;
import java.lang.annotation.*;
import java.lang.reflect.Field;
//通过反射操作注解
public class Test11 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.java.reflection.Student2");
//通过反射获取注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);//@com.java.reflection.TableTest(value=db_student)
}
//获得注解的value的值
TableTest tableTest = (TableTest)c1.getAnnotation(TableTest.class);
String value = tableTest.value();
System.out.println(value);//db_student
//获得类指定的注解
Field id = c1.getDeclaredField("id");
FieldTest annotation = id.getAnnotation(FieldTest.class);
System.out.println(annotation.columnName());//db_id
System.out.println(annotation.type());//int
System.out.println(annotation.length());//10
}
}
@TableTest("db_student")
class Student2{
@FieldTest(columnName = "db_id", type = "int", length = 10)
private int id;
@FieldTest(columnName = "db_age", type = "int", length = 10)
private int age;
@FieldTest(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 TableTest{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldTest{
String columnName();
String type();
int length();
}
(文章通过狂神说视频总结。)