一、定义注解
- 使用前提:使用@interface来进行声明,会自动继承
java.lang.annotation.Annotation
接口 - 注解中的每一个方法实际上是声明了一个配置参数,方法的名称就是参数的名称,返回值的类型就是参数的类型,返回值只能是基本类型、Class、String、Enum,可以通过default关键字声明参数的默认值
[public|final] @interface 注解名
{
注解元素
}
- 注意:(1)不可与i继承其他注解或者接口;(2)@interface只能用来声明一个注解;(3)注解元素是一个无参数方法,方法的类型表示注解的类型
数据类型 注解元素名() [default 默认值];
- 如果只有一个注解元素,在注解元素名为value的情况下,在使用的时候就可以不写出注解元素名,只需要给出注解值即可。
- 使用位置:前一行或者同一行,并且在自定义注解后面的括号中写出注解的值。(不写则是默认值)
1.注解元素的值
- 注解元素一定要有确切的值,可以在定义的时候指定他的默认值,也可以在使用注解的时候指定默认值,非基本类型的注解元素的值不能为null,因此经常使用空字符串或者0作为默认值。
package com.bjpowernode.java_learning;
import java.lang.annotation.Retention;
import java.lang.reflect.Field;
@Retention(RetentionPolicy.RUNTIME)
@interface ApplianceMaker
{
public String type() default "电视机";
public String id() default "001";
public String maker() default "TCL有限公司";
public String address() default "广东省惠州市";
}
@Retention(RetentionPolicy.RUNTIME)
@interface ApplianceSaler {
public String name() default "京东";
public String id() default "001";
public String address() default "北京";
}
@Retention(RetentionPolicy.RUNTIME)
@interface AppliancePrice{
public int value() default 1200;
}
class Appliance{
@ApplianceMaker(type="电脑",id="201")
public String maker;
@ApplianceSaler(name="苏宁",id="222",address="南京")
public String saler;
@AppliancePrice(999)
public int price;
public void setMaker(String m) {
maker = m;
}
public String getMaker() {
return maker;
}
public void setSaler(String saler) {
this.saler = saler;
}
public String getSaler() {
return saler;
}
public void setPrice(int price) {
this.price = price;
}
public int getPrice() {
return price;
}
}
public class D144_1_Test {
public static void main(String[] args) {
System.out.println(readAnnotation(Appliance.class));
}
private static String readAnnotation(Class aClass) {
String maker="制造商:";
String saler="销售商:";
String price="价格:";
Field fields[] = aClass.getDeclaredFields();
for(Field aField:fields) {
if(aField.isAnnotationPresent(ApplianceMaker.class)) {
ApplianceMaker aMaker;
aMaker = (ApplianceMaker)aField.getAnnotation(ApplianceMaker.class);
maker+=aMaker.type() + " ";
maker+=aMaker.id() + " ";
maker+=aMaker.maker() + " ";
maker+=aMaker.address() + "
";
}else if(aField.isAnnotationPresent(ApplianceSaler.class)) {
ApplianceSaler aSaler;
aSaler=(ApplianceSaler)aField.getAnnotation(ApplianceSaler.class);
saler+=aSaler.name()+" ";
saler+=aSaler.id() +" ";
saler+=aSaler.address() + "
";
}else if(aField.isAnnotationPresent(AppliancePrice.class)) {
AppliancePrice thePrice;
thePrice = (AppliancePrice)aField.getAnnotation(AppliancePrice.class);
price+=thePrice.value();
}
}
return maker+saler+price;
}
}
二、反射
- 定义:程序可以访问、检测和修改它本身状态或者行为的一种能力
- 作用:使程序代码能够得到装载到Java虚拟机中的类的内部信息
- Java语言的反射机制:对于任何一个对象,都能够知道这个对象所在的类的所有方法和属性,都能够调用它的任意一个方法和访问属性
- 反射机制的功能:(1)运行时判断任意一个对象所属的类;(2)运行时构造人一个类的对象;(3)运行时判断人一个类所具有的成员变量和方法;(4)生成动态代理。
1.反射类的内容
- 包括
java.lang.Class
类和java.lang.reflect
包中的Field类、Constructor类、Method类和Array类
2.Class类
- 该类的实例表示正在运行的Java应用程序中的类和接口,它是Java反射的基础,对于任何一个类,首先要产生一个Class对象,然后才可以通过Class类获得其他信息。
3.Field类
- 该类提供有关类和接口的单个字段的信息以及对它的动态访问权限,反射的字段可能是一个类(静态)字段或者实例字段,该类封装了反射类的属性。
4.Method类
- 该类提供了关于类和接口上单独某个方法的信息,该方法可能时类方法或者实例方法(包括抽象方法)。该类是用来封装反射类的方法。
5.Constructor类
- 该类提供了关于类的单个构造方法的信息以及对它的访问权限,该类封装了反射类的构造方法
6.Array类
- 该类提供了动态创建和访问Java数组的方法,它提供的方法都是静态方法。
三、讲解Class类
Object obj = new Object();
Class c1 = obj.getClass();
class c2 = Class.forName("java.lang.Integer");
Class c3 = Integer.class;
类型 |
方法 |
说明 |
Class |
forName(String className) |
返回指定字符串名的类或者接口的Class类对象 |
String |
getName() |
返回此Class对象所表示的实体的全限定名 |
Constructor |
getConstructor(Class.. parameterTypes) |
返回此Class对象所表示的实体的指定public构造方法 |
Constructor[] |
getConstructor() |
返回所有的public构造方法 |
Constructor |
getDeclaredConstructor(Class.parameterTypes) |
返回Class类对象所表示的实体的指定构造方法 |
Constructor[] |
getDeclaredConstructors() |
返回所有的构造方法 |
Annotation[] |
getDeclardAnnotations() |
返回此元素上的所有的注解 |
Field |
getField() |
返回此Class对象所表示的类或者接口指定的public字段 |
Field[] |
getFields() |
...............实体的所有的public字段 |
Field[] |
getDeclaredFields(String name) |
.......实体的所有字段 |
Class[] |
getInterface() |
.......类或者接口实现的所有接口Class列表 |
Method |
getMethod(String name,Class...paramterTypes) |
返回指定的方法,name时指定的方法的名称,parametersTypes是指定方法的参数数据类型 |
package com.bjpowernode.java_learning;
import java.lang.reflect.*;
public class D144_4_ClassTest {
public static void main(String[] args) {
try {
Class c = Class.forName("java.util.Date");
Package p = c.getPackage();
String pname = p.getName();
System.out.println("Date类包信息:"+p);
System.out.println("Date类包名"+pname);
int m = c.getModifiers();
String str = Modifier.toString(m);
System.out.println("Date的修饰符:"+str);
System.out.println("Date类名:"+c.getName());
Field[] f = c.getDeclaredFields();
System.out.println("---循环输出Date类中的字段名---");
for(Field field:f) {
System.out.print(field.getName() + " ");
}
System.out.println();
Constructor[] con = c.getDeclaredConstructors();
System.out.println("--循环输出Date类中的构造方法信息---");
for(Constructor cc:con) {
System.out.println(cc.getName() + "的修饰符:"+Modifier.toString(cc.getModifiers()));
Parameter[] ps = cc.getParameters();
System.out.println(cc.getName() + "的参数:");
for(Parameter pp :ps) {
System.out.print(pp.getName() + " ");
}
System.out.println();
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}
}
}
144.1
四、源码:
https://github.com/ruigege66/Java/blob/master/D144_1_Test.java
https://github.com/ruigege66/Java/blob/master/D143_2_SubClass.java
https://github.com/ruigege66/Java/blob/master/D143_3_Test.java
https://github.com/ruigege66/Java/blob/master/D144_4_ClassTest.java
- https://github.com/ruigege66/Java/tree/master/ibank
- 欢迎关注微信公众号:傅里叶变换,个人账号,仅用于技术交流
1000.0