Annotation 的作用:
Annotation 的格式:注解是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWamings(value="unchecked")
Annotation 使用:可以附加在 package、class、method、field等上面,相当于给他们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问
元注解:元注解的作用就是负责注解其他注解,Java定义了4个标准的meta-annotation类型,他们被用来提供对其他annotation类型作说明
//Target:表示注解可以用在哪里
@Target(value = ElementType.METHOD)
//Retention:表示注解在什么地方还有效
@Retention(value = RetentionPolicy.RUNTIME)
//Documented:表示是否将注解生成在JAVAdoc中
@Documented
//Inherited:子类可以继承父类的注解
@Inherited
@interface MyAnnotation{
}
使用@interface自定义注解时,自动继承java.lang.annotation.Annotation接口
public class Demo02 {
//注解可以显式赋值,如果没有默认值,我们就必须给注释赋值
@MyAnnotation1(name = "study",age = 20,id = 001)
public void test(){
}
//注解只有一个参数,且参数名为"value",可以省略参数名,直接写参数
@MyAnnotation2("study")
public void test1(){
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
//注解的参数:参数类型 + 参数名();
String name() default "";
int age() default 18;
int id() default -1;//如果默认值为-1,代表不存在
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
String[] value();
}
动态语言:在运行时可以改变其结构的语言,例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点就是在运行时代码可以根据某些条件改变自身结构
静态语言:运行时结构不可变的语言
Reflection(反射):反射机制允许程序在执行期借助 Reflection API 取得任何类的内部信息,并能直接操作任意对象的内部属性及方法。加载完类之后,在堆内存的方法区中产生了一个class类型的对象(一个类只有一个class对象),这个对象包含了完整的类的结构信息,通过这个对象就可以看到类的结构
//反射
public class Demo03 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取类的Class对象
Class c1 = Class.forName("com.hui.base0328.User");
System.out.println(c1);
Class c2 = Class.forName("com.hui.base0328.User");
Class c3 = Class.forName("com.hui.base0328.User");
Class c4 = Class.forName("com.hui.base0328.User");
//一个类在内存中只有一个Class对象
//一个类被加载后,类的整个结构都会被封装在Class对象中
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
}
}
//实体类
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;
}
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;
}
@Override
public String toString() {
return "User{" +
"name=‘" + name + ‘\‘‘ +
", id=" + id +
", age=" + age +
‘}‘;
}
}
public class Demo04 {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
System.out.println("这个人是:"+person.name);
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1);
//方式二:forname获得
Class c2 = Class.forName("com.hui.base0328.Student");
System.out.println(c2);
//方式三:通过类名.class获得
Class c3 = Student.class;
System.out.println(c3);
//方式四:基本内置类型的包装类都有一个Type属性
Class c4 = Integer.TYPE;
System.out.println(c4);
//方式五:获得父类类型
Class c5 = c1.getSuperclass();
System.out.println(c5);
}
}
class Person{
public String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name=‘" + name + ‘\‘‘ +
‘}‘;
}
}
class Student extends Person{
public Student() {
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher() {
this.name = "老师";
}
}
类加载过程:
发生类初始化的情况:
通过反射可以获取运行时类的完整结构:Field、Method、Constructor、Superclass、Interface、Annotation
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
Class c1 = Class.forName("com.hui.base0328.User");
//1.获得类的名字
System.out.println(c1.getName()); //获得包名 + 类名
System.out.println(c1.getSimpleName()); //获得类名
System.out.println("============================");
//2.获得类的属性
Field[] fields = c1.getFields(); //只能找到public属性
for (Field field : fields) {
System.out.println(field);
}
fields = c1.getDeclaredFields(); //可以找到全部的属性
for (Field field : fields) {
System.out.println(field);
}
//获得指定属性
Field name = c1.getDeclaredField("name");
System.out.println(name);
System.out.println("============================");
//3.获得类的方法
Method[] methods = c1.getMethods(); //获得本类及其父类的全部public方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("============================");
methods = c1.getDeclaredMethods(); //获得本类的所有方法
for (Method method : methods) {
System.out.println(method);
}
System.out.println("============================");
//获得指定方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName",String.class);
System.out.println(getName);
System.out.println(setName);
System.out.println("============================");
//4.获得类的构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
constructors = c1.getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//获得类的指定构造器
Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
System.out.println(declaredConstructor);
}
}
public class Demo02 {
public static void main(String[] args) throws Exception {
//获得Class对象
Class c1 = Class.forName("com.hui.base0329.User");
//构造一个对象
User user = (User)c1.newInstance(); //本质上是调用了类的无参构造
System.out.println(user);
//通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
Object user2 = constructor.newInstance("学习", 03, 29);
System.out.println(user2);
//通过反射调用方法
User user3 = (User)c1.newInstance();
//通过反射获取一个方法
Method setName = c1.getMethod("setName", String.class);
//invoke:激活
//(对象,方法值)
setName.invoke(user3,"学习");
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());
}
}
Java 采用泛型擦除的机制来引入泛型,Java 中的泛型仅仅是给编译器javac使用的,确保数据的安全性和免去强制类型转换的问题。但是,一旦编译完成,所有和泛型有关的类型全部擦除。可以通过方式来获得泛型
public class Demo03 {
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 method = Demo03.class.getMethod("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 = Demo03.class.getMethod("test02", null);
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument);
}
}
}
}
public class Demo04 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("com.hui.base0329.Student2");
//通过反射获得注解
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获得注解的value的值
TableStudy tableStudy = (TableStudy) c1.getAnnotation(TableStudy.class);
String value = tableStudy.value();
System.out.println(value);
//获得类指定的注解
Field name = c1.getDeclaredField("name");
FieldStudy annotation = name.getAnnotation(FieldStudy.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
@TableStudy("db_student")
class Student2{
@FieldStudy(columnName = "db_id",type = "int",length = 10)
private int id;
@FieldStudy(columnName = "db_age",type = "int",length = 10)
private int age;
@FieldStudy(columnName = "db_naeme",type = "varchar",length = 3)
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 TableStudy{
String value();
}
//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldStudy{
String columnName();
String type();
int length();
}
原文:https://www.cnblogs.com/njhblog/p/14591501.html