一:注解
1.注解格式:@“注解名“
2.内置注解:@Override,@Deprecated,@SuppressWarnings
3.元注解: @Target,@Retention(RUNTIME>CLASS>SOURCE),@Document,@Inherited
4.自定义注解:a.@interface自动继承了Annotation接口了
b.注解参数:参数类型+参数名()
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Main {
@MyAnnatation01(name="张三")
public void func01(){
System.out.println();
}
@MyAnnatation02("张三")
public void func02(){
System.out.println();
}
@MyAnnatation03(age=22)
public void func03(){
System.out.println();
}
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnatation01{
String name();
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnatation02{
String value();
}
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnatation03{
String name() default "";
int id()default -1;
int[] score()default {85,75,60};
int age();
}
二:反射
1.反射概述:
1.java是静态语言,通过反射变为了准动态语言
2.反射很强大,可以通过Refletion API任何类的内部信息,并能操作任意对象的内部属性及方法
3.四种获取Class对象方式(类名):
(1. forname(“包名下的路径”)
(2. 对象名.getClass()
(3. 类名.class
(4. 基本类型包装类.Type
5.一种获取其父类的Class对象方式: 对象名.getSuperClass()
6.类被加载后,其该类的整体结构被封装到Class对象中,在内存中,一个类只有一个Class对象
package reflection;
import java.lang.annotation.ElementType;
public class Main {
public static void main(String[] args) throws ClassNotFoundException {
Person user = new Person();
Class c1 = Class.forName("reflection.Person");
Class c2 = Class.forName("reflection.Person");
System.out.println("c2 = " + c2);
Man man = new Man();
Class c3 = man.getClass();
System.out.println("c3 = " + c3);
Class c4 = Person.class;
System.out.println("c4 = " + c4);
Class c5 = Man.class;
System.out.println("c5 = " + c5);
Class c6 = Main.class;
System.out.println("c6 = " + c6);
Class c7 = Integer.TYPE;
System.out.println("c7 = " + c7);
System.out.println("c8 = " + c3.getSuperclass());
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c6.hashCode());
System.out.println("-------------");
showAllClass();
}
public static void showAllClass(){
Class c1 = Object.class;
Class c2 = Comparable.class;
Class c3 = int[].class;
Class c4 = int[][].class;
Class c5 = Override.class;
Class c6 = ElementType.class;
Class c7 = Integer.class;
Class c8 = Void.class;
Class c9 = Class.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
System.out.println(c5);
System.out.println(c6);
System.out.println(c7);
System.out.println(c8);
System.out.println(c9);
System.out.println("-----------");
int[] a1 =new int[10];
int[] a2=new int[100];
System.out.println(a1.getClass());
System.out.println(a2.getClass());
}
}
class Person {
String name;
int age;
public int id;
public Person(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public Person() {
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
private void test(){}
}
class Man extends Person{
}
2.初识类加载内存机制:
1.类加载:将Class字节码文件加载到内存中,对应生成唯一的Class对象(方法区——>堆)
2.链接:为所有类变量(static)分配内存并为其设置默认初始值(方法区)
3.初始化:<clinit>()将所有赋值动作和静态代码块合并(栈)
package reflection;
public class ClassLoading01 {
static{
System.out.println("Main被加载");
}
public static void main(String[] args) throws ClassNotFoundException {
ClassMemory();
Son son=new Son();
}
public static void ClassMemory(){
A a=new A();
System.out.println(a.m);
}
}
class A{
static{
System.out.println("静态代码块初始化");
m=300;
}
public static int m=100;
A(){
System.out.println("A的构造函数调用");
}
}
class Father{
static {
System.out.println("父类被加载");
}
public static int mFather=1;
}
class Son extends Father{
static {
System.out.println("子类被加载");
}
public static int mSon=1;
public static final int nFinalSon=2;
}
3.初识类加载器:
一.类加载器:
1.系统类加载器:ClassLoader.getSystemClassLoader()
2.扩展类加载器:systemClassLoader.getParent()
3.引导类(根)加载器(C/C++编写):扩展类加载器.getParent()
4.测试当前类和内置类的加载器
5.获取系统加载器可以加载的路径:同4获取class对象.getClassLoader()
6.双亲委派机制
二.获取类运行时结构:
1.获取类名(全包名,只类名):Class对象.getName()
2.获取属性值(公有,所有,指定):
公有: Class对象.getFields()
所有:Class对象.getDeclaredFields()
指定:对应方法去掉s+属性名参数
3.获取方法(公有,所有,指定):
公有:Class对象.getMethods()
所有:Class对象.getDeclaredMethods()
指定:对应方法去掉s+函数名参数
4.获取构造方法(公有,指定)
公有:Class对象.getConstructors()
指定:对应函数去掉s+实际参数的class
三:反射动态创建对象并执行方法:
1.无参创建对象和有参创建:
无参:Class对象.newInstance()
有参:Class对象..getConstructor(实际参数的Class对象)
2.获取方法并调用:
获取:Class对象.getMethod("方法名", 参数的Class对象)
调用:方法名.invoke(创建的对象名, 参数)
3.操作属性并调用
权限检测:创建的对象名.setAccessible(true),ture为关闭
调用:获取属性名后.set(创建的对象名,参数)
四:对象调用性能对比分析:
1.普通对象调用(约3ms)
2.通过反射调用(约3592ms)
3.通过反射调用并关掉安全性权限检测(约1847ms)
4.若频繁调用反射,可关闭安全检测提升性能
package reflection;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ClassLoading02 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
classLoadTest();
getClassRuning();
createClassRuning();
performanceAnalyze();
}
public static void classLoadTest() throws ClassNotFoundException {
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);
ClassLoader parent1 = systemClassLoader.getParent();
System.out.println(parent1);
ClassLoader parent2 = parent1.getParent();
System.out.println(parent2);
Class<?> aClass = Class.forName("reflection.ClassLoading02");
System.out.println(aClass.getClassLoader());
ClassLoader classLoader = Class.forName("java.lang.Object").getClassLoader();
System.out.println(classLoader);
System.out.println(System.getProperty("java.class.path"));
}
public static void getClassRuning() throws NoSuchFieldException, NoSuchMethodException {
System.out.println("----------------");
Person person = new Person();
Class<? extends Person> aClass = person.getClass();
String name = aClass.getName();
String simpleName = aClass.getSimpleName();
System.out.println("全名:" + name);
System.out.println("类名" + simpleName);
System.out.println("----------------");
Field[] declaredFields = aClass.getDeclaredFields();
Field[] fields = aClass.getFields();
Field field = aClass.getDeclaredField("name");
Field id = aClass.getField("id");
for (Field declaredField : declaredFields) {
System.out.println("所有属性:"+declaredField);
}
for (Field field1 : fields) {
System.out.println("公有属性:"+field);
}
System.out.println("指定私有属性:" + field);
System.out.println("指定共有属性:"+id);
System.out.println("----------------------");
Method[] methods = aClass.getMethods();
Method[] declaredMethods = aClass.getDeclaredMethods();
Method getId = aClass.getMethod("setId", int.class);
Method test = aClass.getDeclaredMethod("test", null);
for (Method method : methods) {
System.out.println("共有方法:"+method);
}
for (Method declaredMethod : declaredMethods) {
System.out.println("所有方法:"+declaredMethod);
}
System.out.println("指定共有方法:" + getId);
System.out.println("指定私有方法:"+test);
System.out.println("-------------------");
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("获取构造器:"+constructor);
}
Constructor<? extends Person> constructor = aClass.getConstructor(String.class, int.class, int.class);
System.out.println("获取指定构造器:"+constructor);
}
public static void createClassRuning() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
System.out.println("###################");
Class<?> aClass = Class.forName("reflection.Person");
Object o = aClass.newInstance();
System.out.println("反射创建无参对象:"+o);
Constructor<?> constructor = aClass.getConstructor(String.class, int.class, int.class);
Object person = constructor.newInstance("张三", 22, 101);
System.out.println("反射创建有参对象:"+person);
Method setName = aClass.getMethod("setName", String.class);
setName.invoke(person, "李四");
System.out.println("反射调用函数:"+person);
Field personName = aClass.getDeclaredField("name");
personName.setAccessible(true);
personName.set(person,"王五");
System.out.println("反射操作属性:name:"+personName.get(person));
}
public static void performanceAnalyze() throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException {
System.out.println();
System.out.println("---------------------");
test01();
test02();
test03();
}
public static void test01(){
Person person=new Person("zhangsan",18,28);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
person.getName();
}
long endTime = System.currentTimeMillis();
System.out.println("普通对象调用:"+(endTime-startTime)+"ms");
}
public static void test02() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class aClass = Class.forName("reflection.Person");
Constructor constructor = aClass.getConstructor(String.class, int.class, int.class);
Object person = constructor.newInstance("zhangsan", 18, 28);
Method getName = aClass.getMethod("getName", null);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(person,null);
}
long endTime = System.currentTimeMillis();
System.out.println("通过反射调用:"+(endTime-startTime)+"ms");
}
public static void test03() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class aClass = Class.forName("reflection.Person");
Constructor constructor = aClass.getConstructor(String.class, int.class, int.class);
Object person = constructor.newInstance("zhangsan", 18, 28);
Method getName = aClass.getMethod("getName", null);
getName.setAccessible(true);
long startTime = System.currentTimeMillis();
for (int i = 0; i < 1000000000; i++) {
getName.invoke(person,null);
}
long endTime = System.currentTimeMillis();
System.out.println("通过反射并关闭安全检测调用:"+(endTime-startTime)+"ms");
}
}
4.反射获取泛型信息:
1.获取函数的泛型参数类型:
泛型参数类型:方法名.getGenericParameterTypes()
判断泛型参数为参数化类型:if(genericParameterType instanceof ParameterizedType)
强转为参数化类型:((ParameterizedType) genericParameterType).getActualTypeArguments()
2.获取函数的返回泛型类型:
返回泛型类型:方法名.getGenericReturnType()
判断泛型参数为参数化类型:同上
强转为参数化类型:同上
在这里插入代码片package reflection;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Map;
public class GetGenericityInformantion {
public void test01(Map<String,Person> arg){
}
public Map<String,Person> test02(){
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method test01 = GetGenericityInformantion.class.getMethod("test01", Map.class);
Type[] genericParameterTypes = test01.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 test02 = GetGenericityInformantion.class.getMethod("test02");
Type genericReturnType = test02.getGenericReturnType();
System.out.println("函数返回的泛型类型:"+genericReturnType);
if (genericReturnType instanceof ParameterizedType){
Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println("函数返回的泛型信息:"+actualTypeArgument);
}
}
}
}
5.反射调用注解:
1.反射调用类的注解的value
2.反射调用类属性的注解value
package reflection;
import com.sun.jdi.Value;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class ReflectionCallAnnotation {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> c1 = Class.forName("reflection.Student");
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("获取类注解信息:"+annotation);
}
ClassAnnotation annotation = (ClassAnnotation)c1.getAnnotation(ClassAnnotation.class);
System.out.println("获取类注解的value():"+annotation.value());
Field[] declaredFields = c1.getDeclaredFields();
for (Field declaredField : declaredFields) {
FieldAnnotation annotation1 = declaredField.getAnnotation(FieldAnnotation.class);
System.out.println("获取类属性的直接信息:"+"<"+declaredField.getName()+">"+annotation1.name()+" "+annotation1.type()+" "+annotation1.length());
}
}
}
@ClassAnnotation("db_student")
class Student{
@FieldAnnotation(name="sName",type ="varchar",length = 5)
private String sName;
@FieldAnnotation(name="nIage",type = "int",length = 6)
private int nIge;
@FieldAnnotation(name = "sId",type = "varchar",length = 12)
private String sId;
public Student() {
}
public Student(String sName, int nIge, String sId) {
this.sName = sName;
this.nIge = nIge;
this.sId = sId;
}
@Override
public String toString() {
return "Student{" +
"sName='" + sName + '\'' +
", nIge=" + nIge +
", sId='" + sId + '\'' +
'}';
}
public void setsName(String sName) {
this.sName = sName;
}
public void setnIge(int nIge) {
this.nIge = nIge;
}
public void setsId(String sId) {
this.sId = sId;
}
public String getsName() {
return sName;
}
public int getnIge() {
return nIge;
}
public String getsId() {
return sId;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ClassAnnotation{
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation{
String name();
String type();
int length();
}
|