2021-01-22

Java学习-注解和反射

注解

java.Annotation

Annotation的作用:可以呗其他程序读取

Annotation的格式

  • 注解是:@注释名 在代码中存在,还可以添加一些参数

    ​ @SuppressWarnings(values="unchecked")

  • 通过反射,可以访问数据。

内置注解

@override:定义在java.lang.Override中,此注解只适用于修饰方法,标识一个方法声明打算重写父类的另一个方法。

@Deprecated:定义在java.lang.Deprecated中,此方法用于修饰方法,类,属性。表示废弃元素

@SuppressWarings:定义在java.lang.SuppressWarings中,用来抑制编译时的警告信息。

  • 此方法需要传入参数。
public class Demo01 extends Object { //重写的注解 @Override public String toString() {  return super.toString(); } //不推荐使用的注解,但是可以使用 @Deprecated public static void test() {  System.out.println("Deprecated"); } @SuppressWarnings("all") public static void test2() {  ArrayList arrayList = new ArrayList(); } public static void main(String[] args) {  test(); }}

元注解

元注解就是负责注解其他的注解,Java定义了四个标准的meta-annotation类型,他们用来提供对其他annotation类型操作说明

可以从java.lang.annotation中找到(@Target,@Retention,@Docimented,@Inherited

@Target:用于描述注解的使用范围({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}

@Retention:标识需要在什么级别保存该注解信息,用于描述注解的生命周期(SOURCE<CLASS<RENTIME

@Docimented:说明注解将被包含在javadoc中

@Inherited:说明子类可以继承父类中的该注解

自定义注解

使用@interface自定义注解

格式

public @interface MyAnnotation{}
public class Demo02 { //注解可以显示的复制,如果没有默认值,就一定要注解赋值 @MyAnnotation(name = "nice",schools = {"1234","2314"}) public void test(){}@MyAnnotation2("sdf") public void test2(){}}@Target(value = {ElementType.METHOD,ElementType.TYPE})@Retention(value =RetentionPolicy.RUNTIME)@interface MyAnnotation{ //注解的参数:参数类型 参数名(); String name() default ""; int age() default 0; int id() default -1;//代表不存在。 String[] schools() default {"erq","asds"};}@Target(value = {ElementType.METHOD,ElementType.TYPE})@Retention(value =RetentionPolicy.RUNTIME)@interface MyAnnotation2{ //注解的参数:参数类型 参数名(); String value() default "";}

反射

java.Reflection

反射机制允许程序在执行期间借助Reflection API获取任何类的内部信息,并能直接操作任意对象的内部属性级方法

Class c= Class.forName("java.lang.String")

获得反射对象

public class Demo03 { public static void main(String[] args) throws ClassNotFoundException {  //通过反射获取类的class对象  Class c1 = Class.forName("com.darker.demo01.User");  Class c2 = Class.forName("com.darker.demo01.User");  Class c3 = Class.forName("com.darker.demo01.User");  //一个类在内存中只有一个Class对象  //一个类被加载后,类的整个结构都会被装在Class对象中  System.out.println(c1.hashCode());  System.out.println(c2.hashCode());  System.out.println(c3.hashCode()); }}

Class对象

方法名功能说明
static ClassforName(String name)返回指定类名name的Class对象
Object newInstance()调用缺省构造函数,返回Class对象的一个实例
getName()返回此Class对象锁标识的实体(类、接口、数组类或void)的名称
Class getSuperClass()返回房钱Class对象的父类的Class对象
Class[] getinterfaces()获取房钱Class对象的接口
ClassLoader getClassLoader()返回该类的类加载器
Constructor[] getConstructors()返回一个包含某些Constructor对象的数组
Method getMethod(String name,Class...T)返回一个Method对象,此对象的类型类paramaType
Field[] GetDeclaredFields()返回Field对象的一个数组

获取Class对象

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.hashCode());  //方式二:forname获得  Class c2 = Class.forName("com.darker.demo01.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.hashCode());  //获得父类类型  Class c5 = c1.getSuperclass();  System.out.println(c5); }}class Person{ public String name; public Person() { } 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 = "老师"; }}

哪些类型有Class对象

class:外部类,成员内部类,静态内部类,局部内部类,局部内部类,匿名内部类。

interface:接口

[]:数组

enum:枚举

annotation:注解@interface

primitive type:基本数据类型

void

class内存分析

public class Demo05 { public static void main(String[] args) {  A a = new A();  System.out.println(A.m);  /*  1.加载到内存,会产生一个类的对应的Class对象  2.链接,链接后m=0  3.初始化  	<cinit>(){  		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类的无参构造初始化"); }}

打印结果:

A类静态代码块初始化
A类的无参构造初始化
100

类的初始化

类的主动引用(一定会发生类的初始化)

  • 当虚拟机启动,先初始化main方法所在的类
  • new一个类对象
  • 调用静态成员(除了final常量)和静态方法
  • 使用java.lang.reflect包的方法惊醒反射调用
  • 当初始化一个类,如果其父类没有初始化,咋会初始化它的父类

类的被动引用(一定不会发生类的初始化)

  • 通过数组定义类引用
  • 引用常量触发此类的初始化(常量在链接阶段就存入调用类的常量池中)
  • 当访问一个静态域,只有真正声明这个域的类才会被初始化。如:通过子类调用父类的静态变量。

类加载器

引导类加载器

扩展类加载器 ExtClassLoader 负责jre/lib/ext目录下的jar包或者-D java.ext.dirs指定目录下的jar包装入工作库

系统类加载器 AppClassLoader 负责java -classpath或-D java.class.path所指的目录下的类与jar包装如工作库,是最常用的加载器

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("com.darker.demo01.Demo06").getClassLoader();  System.out.println(classLoader);  //如何获取系统类加载器可以加载的路径  System.out.println(System.getProperty("java.class.path")); }}

获取类的信息

public class Demo07 { public static void main(String[] args) throws ClassNotFoundException {  Class aClass = Class.forName("com.darker.demo01.User");  //获得类的名字  System.out.println("获得类的名字");  //获得包名+类名  System.out.println(aClass.getName());  //获得类名  System.out.println(aClass.getSimpleName());  //获得类的属性  System.out.println("获得类的属性");  //只能找到public属性  Field[] fields = aClass.getFields();  for (Field field : fields) {   System.out.println(field);  }  //能找到全部属性  Field[] declaredFields = aClass.getDeclaredFields();  for (Field field : declaredFields) {   System.out.println(field);  }  //获得类的方法  System.out.println("获得类的方法");  //获得本类和父类的所有public方法  Method[] methods = aClass.getMethods();  for (Method method : methods) {   System.out.println(method);  }  System.out.println("=========================");  //获得本类所有方法  Method[] declaredMethods = aClass.getDeclaredMethods();  for (Method declaredMethod : declaredMethods) {   System.out.println(declaredMethod);  } }}

通过反射操作类

public class Demo08 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, NoSuchFieldException {  Class c1 = Class.forName("com.darker.demo01.User");  //构造一个对象  User user1 = (User) c1.newInstance();  System.out.println(user1);  //通过构造器创建对象  Constructor constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);  Object user2 = constructor.newInstance("Darker", 1, 22);  System.out.println(user2);  //通过反射调用普通方法  User user3 = (User) c1.newInstance();  Method setName = c1.getDeclaredMethod("setName", String.class);  //invoke激活。(对象,"方法值")  setName.invoke(user3, "darkerJO");  System.out.println(user3);  //通过反射操作属性  User user4 = (User) c1.newInstance();  Field name = c1.getDeclaredField("name");  //不能直接操作私有属性,需要关闭程序的安全监测,属性或方法的setAccessible(true)  name.setAccessible(true);  name.set(user4, "DarkerGuo");  System.out.println(user4); }}








原文转载:http://www.shaoqun.com/a/512526.html

跨境电商:https://www.ikjzd.com/

跨境通电子商务:https://www.ikjzd.com/w/1329

沃尔码:https://www.ikjzd.com/w/220


注解java.AnnotationAnnotation的作用:可以呗其他程序读取Annotation的格式注解是:@注释名在代码中存在,还可以添加一些参数​ @SuppressWarnings(values="unchecked")通过反射,可以访问数据。内置注解@override:定义在java.lang.Override中,此注解只适用于修饰方法,标识一个方法声明打算重写父
败欧洲运费:败欧洲运费
心怡:心怡
2020香港春节什么地方放烟花?:2020香港春节什么地方放烟花?
致跨境电商新卖家 - 牢牢抓住单一颜色控客户,缩小你的选品范围!:致跨境电商新卖家 - 牢牢抓住单一颜色控客户,缩小你的选品范围!
给你10个畅游海南的理由 :给你10个畅游海南的理由

No comments:

Post a Comment