目录
将p2对象的f2属性赋值位Bob,f2属性位私有属性name
注解:
Annotation,java标注,JDK5引入的一种机制。
java中的类、方法、变量、参数、包都可以被标注
元注解:专门给注解加的注解
在java的整个的注解体系中,有三个重要的主干类
Annotation接口,定义一些常用的方法
ElementType枚举,它用来指定注解的类型
RetentionPolicy枚举,它用来指定注解的策略。不同的类型的策略指定的注解的作用域不同。
SOURCE,注解仅存在于编译器处理期间,编译期处理完之后,这个注解就没用了
CLASS,注解在.class文件中依然有效。
RUNTIME,编译期是不起作用的,只有在运行期才由JVM读取。
Java自带的注解:10个。4个注解在java.lang.annotation
6个注解在java.long
作用在代码上的注解:
1、@Override,检查该方法是否是重写方法。如果返现其父类,或者是引用的接口中没有该方法,会报错
2、@Deprecated,标记的方法,过时的方法。
3、@SuppressWarnings编辑器去忽略警告
4、@SafeVarargs,JDK7支持忽略任何使用参数为泛型变量的方法或构造器产生的警告
5、@FunctionalInterface,JDK8开始支持,表示一个接口为函数式接口
6、@Repeatable,JDK8开始支持,标识某个注解可以在同一个声明上使用多次
all:忽略所有警告
boxing:忽略装箱、拆箱警告
rawtypes:使用生成时没有指定数据类型
unchecked:忽略没有进行类型检查操作的警告
unused:忽略没有使用的警告
元注解:
1、@Retention:标识这个注解作用域
2、@Documented:标记这个注解是否包含在用户文档中
3、@Target:这个注解可以修饰哪些信息
4、@Inherited:如果一个类用上了@Inherited注解,那么其子类也会继承这个注解
可以自己创建注解:
/**
* 这是我们自己创建的注解
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MyAnnotation {
String name() default "tom";
int age();
int value();
}
反射
什么是反射?
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态(或准动态,为啥要说是准动态,因为一般而言的动态语言定义是程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。)语言的一个关键性质。
反射能做些什么?
我们知道反射机制允许程序在运行时取得任何一个已知名称的class的内部信息,包括包括其modifiers(修饰符),fields(属性),methods(方法)等,并可于运行时改变fields内容或调用methods。那么我们便可以更灵活的编写代码,代码可以在运行时装配,无需在组件之间进行源代码链接,降低代码的耦合度;还有动态代理的实现等等;但是需要注意的是反射使用不当会造成很高的资源消耗!
反射的具体实现:
获取类对象:
ps:已经创建了Dog类
1.直接使用类名.class
Class<Dog> class = Dog.class;
2.获取类的名字
class.getName()
3.获取类的加载器
ClassLoader classLoader = class.getClassLoader();
4.获取资源
URL resource = class.getResource("");
5.获取父类
class.getSuperclass();
6.判断一个类是不是接口,数组
class.isArray();
class.isInterface();
7.使用class类对象实例化一个对象
Dog dog = class.newInstance();
8.使用全类名
Class aclass = Class.forName("com.morning.Dog");
9.使用对象
Dog dog = new Dog(); Class aClass1 = dog.getClass();
Class方法:
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
对成员变量的操作
Class<Dog> class = Dog.class;
只能获取public的属性:
Field type = clazz.getField("type");//获取指定属性
System.out.println(type);
Field[] fields = clazz.getFields();
System.out.println(Arrays.toString(fields));
可以获取private的属性:
Field name = clazz.getDeclaredField("name");
System.out.println(name);
System.out.println(name.getType());
Field[] declaredFields = clazz.getDeclaredFields();
System.out.println(Arrays.toString(declaredFields));
获取对象的属性
Dog dog = new Dog();
dog.setType("金毛");
Dog dog1 = new Dog();
dog1.setType("泰迪");
Class<Dog> clazz = Dog.class;
Field type = clazz.getDeclaredField("type");
// 想要获取哪一个对象的color
String str = (String) type.get(dog1);
System.out.println(str);
获得类的所有方法
Method [] allMethods = c2.getDeclaredMethods();
for(Method method : allMethods){
System.out.println(method.getName());//work say
}
通过反射去调用构造器
Constructor [] constructors = c2.getConstructors();
for(Constructor constructor : constructors){
System.out.println(constructor.toString());//public com.ys.reflex.Person()
}
启用和禁用访问安全检查的开关
值为 true,则表示反射的对象在使用时应该取消 java 语言的访问检查;反之不取消
f2.setAccessible(true);
System.out.println(f2);
将p2对象的f2属性赋值位Bob,f2属性位私有属性name
f2.set(p2,"Bob");
System.out.println(f2.get(p2)); //Bob
使用反射机制可以打破封装性,导致了java对象的属性的不安全。
总结
今天学习了注解和反射,大概了解代码中@字符的作用和意义,晚上又将字符流复习了一遍,感觉良好