注解 annotation:给程序和人看
注释 comment:给人看
// 内置注解
public class MyFirstAnnotation extends Object{
// 重写的注解
@Override
public String toString() {
return super.toString();
}
// 不推荐程序员使用,但是可以使用。或者存在更好的方式
@Deprecated
public static void testDeprecated(){
System.out.println("testDeprecated");
}
// 用来抑制编译时的警告信息 ,需要添加参数
@SuppressWarnings("all")
public static void testSuppressWarnings(){
System.out.println("testSuppressWarnings");
}
public static void main(String[] args) {
testDeprecated();
}
}
import java.lang.annotation.*;
//测试元注解
@MyMetaAnnotationDemo
public class MyMetaAnnotation {
@MyMetaAnnotationDemo
public void testMyMetaAnnotationDemo(){
System.out.println("1");
}
}
// @interface 定义一个注解
// @Target 规定它在哪里有效,是类的上面,还是方法的上面
// @Retention 规定注解在什么时候有效 RUNTIME>CLASS>SOURCE
// @Documented 是否将我们的注解生成在Javadoc中
// @Inherited 子类可以继承父类的注解
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface MyMetaAnnotationDemo{
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 自定义注解
public class MyDefinedAnnotation {
// 如果是 default 则可以不传参数, 否则必须
@MyDefinedAnnotationDemo1(name = "String",id=123)
public void testMyDefinedAnnotationDemo1(){}
// 如果只有一个参数,value 则不需要写 value="String",直接 "String"
@MyDefinedAnnotationDemo2("String")
public void testMyDefinedAnnotationDemo2(){}
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyDefinedAnnotationDemo1{
// 注解的参数: 参数类型+参数名()
String name();
// 默认值
int id() default 123;
int age() default 99;
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface MyDefinedAnnotationDemo2{
String value();
}
package ReflectionDemo;
// 反射
public class MyFirstReflection {
public static void main(String[] args) throws ClassNotFoundException {
// 通过反射获取类的 class 对象
Class c1 = Class.forName("ReflectionDemo.User");
System.out.println(c1);
// 一个类在内存中只有一个Class对象
// 一个类被加载后,类的整个结构都会被封装在Class对象中
Class c2 = Class.forName("ReflectionDemo.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
}
}
// 实体类
class User{
private String name;
private int id;
private int age;
public User() {
}
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
@Override
public String toString() {
return "user{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
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;
}
}
// Class类的创建方式
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
// 方式一 通过实例对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
// 方式二 通过forName获得
Class c2 = Class.forName("CreateClassDemo.Student");
System.out.println(c2.hashCode());
// 方式三 通过类名.class 获得 !!推荐
Class c3 = Student.class;
System.out.println(c3.hashCode());
// 方式四 基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4); //int
// 获得父类的信息
Class c5 = c1.getSuperclass();
System.out.println(c5); //Person
}
}
class Person{
public String name;
}
class Student extends Person{
Student(){
this.name = "Student";
}
}
class Teacher extends Person{
Teacher(){
this.name = "Teacher";
}
}
// 类加载内存分析
public class Demo {
public static void main(String[] args) {
A a = new A();
System.out.println(a.m); //100,和m赋值的顺序有关系
/*
1.加载, 将class文件加载到内存,在堆中生成对应的Class对象,唯一的,方法区有对应类的方法属性等
2.链接, 为static分配内存并设置默认初始化,链接结束后 m=0
3.初始化,会合并静态代码块和属性
调用了(){
System.out.println("A类静态代码块初始化");
m = 300;
static int m = 100;
}
*/
}
}
class A{
static {
System.out.println("A类静态代码块初始化");
m = 300;
}
static int m = 100;
public A(){
System.out.println("A类的构造函数");
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// 获取类的信息
public class Demo1 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("GetClassStructure.User");
// 获得类的名字
System.out.println(c1.getName()); //ReflectionDemo.User
System.out.println(c1.getSimpleName()); //User
System.out.println("============================");
// 获得类的属性
Field[] fields = c1.getFields();
// 只能打印 public
for (Field field : fields) {
System.out.println(field);
}
// 可以打印出私有属性
fields = c1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field); //private java.lang.String ReflectionDemo.User.name
}
// 获得指定的属性 (私有的)
System.out.println(c1.getDeclaredField("name")); //private java.lang.String ReflectionDemo.User.name
System.out.println("============================");
// 获得类的方法
// 子类和父类的所有 public 方法
Method[] method = c1.getMethods();
// 只获得子类的所有方法,包括私有的
Method[] declaredMethods = c1.getDeclaredMethods();
// 获得指定的方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println(getName);// public java.lang.String ReflectionDemo.User.getName()
System.out.println(setName);// public void ReflectionDemo.User.setName(java.lang.String)
System.out.println("============================");
// 获得类的构造器
Constructor[] constructor = c1.getConstructors();
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
// 获得指定类型的构造器
Constructor constructor1 = c1.getConstructor(String.class, int.class, int.class);
}
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
// 动态的创建,通过反射
public class Demo2 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
Class c1 = Class.forName("GetClassStructure.User");
// 构造一个对象 newInstance() 必须有无参构造,也可以通过构造器
User user1 = (User) c1.newInstance();
System.out.println(user1); //user{name='null', id=0, age=0}
// 通过构造器创建对象
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
User user = (User) declaredConstructor.newInstance("姓名", 1, 2);
System.out.println(user); //user{name='姓名', id=1, age=2}
// 通过反射调用方法
User user3 = (User) c1.newInstance();
// 通过反射获取方法
Method setName = c1.getDeclaredMethod("setName", String.class);
// invoke激活 (对象,方法的值)
setName.invoke(user3,"invoke名字");
System.out.println(user3.getName()); //invoke名字
// 通过反射操作属性
User user4 = (User) c1.newInstance();
Field name = c1.getDeclaredField("name");
// 私有属性不能被赋值,需要关闭Java语言检测
name.setAccessible(true);
name.set(user4,"set名字");
System.out.println(user4.getName()); //set名字
}
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
// 性能分析
public class Demo3 {
public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, IllegalAccessException {
test1();
test2();
test3();
// 普通方式:4
// 反射方式:130
// 反射+关闭检测方式:96
}
// 普通方式调用
public static void test1(){
User user = new User();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
user.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通方式:"+ (endTime-startTime));
}
// 反射方式调用
public static void test2() throws ClassNotFoundException, 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 < 100000000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射方式:"+ (endTime-startTime));
}
// 反射方式调用 + 关闭检测
public static void test3() throws ClassNotFoundException, 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 < 100000000; i++) {
getName.invoke(user,null);
}
long endTime = System.currentTimeMillis();
System.out.println("反射+关闭检测方式:"+ (endTime-startTime));
}
}
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
// 获取泛型信息
public class Demo4 {
public static void test1(Map<String,User> map){
System.out.println("test1");
}
public static Map<String,User> test2(){
System.out.println("test2");
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = Demo4.class.getDeclaredMethod("test1", Map.class);
// 获得泛型参数类型
Type[] genericParameterTypes = method.getGenericParameterTypes();
for (Type genericParameterType : genericParameterTypes) {
System.out.println("test1##" + genericParameterType);
// 判断是否是参数化类型
if (genericParameterType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("test1真实"+actualTypeArgument);
}
}
}
/*
test1##java.util.Map
test1真实class java.lang.String
test1真实class GetClassStructure.User
*/
method = Demo4.class.getDeclaredMethod("test2");
// 获得泛型参数返回类型
Type genericReturnType = method.getGenericReturnType();
System.out.println("test2##"+genericReturnType);
// 判断是否是参数化类型
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("test2真实"+actualTypeArgument);
}
}
/*
test2##java.util.Map
test2真实class java.lang.String
test2真实class GetClassStructure.User
*/
}
}
ORM Object Relationship Mapping --> 对象关系映射
import java.lang.annotation.*;
import java.lang.reflect.Field;
// 练习反射操作注解
public class Demo5 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("GetClassStructure.Student");
// 通过反射获得类的注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation); //@GetClassStructure.ClassAnnotation(value=db_student)
}
// 获得类注解的value值
ClassAnnotation classAnnotation = (ClassAnnotation) c1.getAnnotation(ClassAnnotation.class);
String value = classAnnotation.value();
System.out.println(value); //db_student
// 获得类属性的注解
Field name = c1.getDeclaredField("name");
FieldAnnotation nameAnnotation = name.getAnnotation(FieldAnnotation.class);
System.out.println(nameAnnotation); //@GetClassStructure.FieldAnnotation(columnName=db_name, type=varchar, length=3)
System.out.println(nameAnnotation.columnName()); //db_name
System.out.println(nameAnnotation.type()); //varchar
System.out.println(nameAnnotation.length()); //3
}
}
@ClassAnnotation("db_student")
class Student{
@FieldAnnotation(columnName = "db_id",type = "int",length = 10)
private int id;
@FieldAnnotation(columnName = "db_age",type = "int",length = 10)
private int age;
@FieldAnnotation(columnName = "db_name",type = "varchar",length = 3)
private String name;
public Student() {
}
public Student(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "student{" +
"id=" + id +
", age=" + age +
", 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;
}
}
// 类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnnotation{
String value();
}
// 属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation{
String columnName();
String type();
int length();
}