注解
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/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