网站建设商虎小程序,广州住房和城乡建设厅网站,安卓优化大师最新版,杭州装饰网站建设方案六.JAVA知识点全面总结6泛型反射和注解
1.什么是泛型?可以用在哪里#xff1f;
2.泛型擦除机制是什么#xff1f;为什么擦除#xff1f;
3.通配符是什么#xff1f;作用是什么#xff1f;
未更新
1.注解是什么#xff1f;有什么用#xff1f;
2.注解的自定义和实…六.JAVA知识点全面总结6泛型反射和注解
1.什么是泛型?可以用在哪里
2.泛型擦除机制是什么为什么擦除
3.通配符是什么作用是什么
未更新
1.注解是什么有什么用
2.注解的自定义和实现机理是什么
3.JAVA编译过程是什么
未更新
1.什么是反射反射的用处
2.反射的结构
3.反射在编译和运行时的理解
未更新
未更新
六.JAVA知识点全面总结6泛型反射和注解
1.什么是泛型?可以用在哪里
①编译器行为
编译器可以对泛型参数进行检测增强代码的可读性或稳定性。
②用法
泛型类 public class PersonT{ }泛型接口public interface PersonT{}泛型方法public static E void print(E[ ] array){}
③项目中
通用的返回结果工具类
④泛型代码
通用的返回结果
package fanxingtest;public class CommonResultT {private String code;//返回状态码private T data;//返回数据private String message;//返回信息public CommonResult(String code, T data, String message) {this.code code;this.data data;this.message message;}public String getCode() {return code;}public T getData() {return data;}public String getMessage() {return message;}public void setCode(String code) {this.code code;}public void setData(T data) {this.data data;}public void setMessage(String message) {this.message message;}Overridepublic String toString() {return CommonResult{ code code \ , data data , message message \ };}
}2.泛型擦除机制是什么为什么擦除
①泛型擦除机制
用于编译器类型检查编译时擦除信息编译器行为不是真的泛型为了兼容老版本故引入泛型机制但不创建新的类型
②泛型擦除机制简介
ListT 编译器擦除为 ListE[ ] Array 编译器擦除为 Object[] Array可通过反射调用方法来存其他类型证明是编译时行为例如ListInteger通过反射可以存储String类型的变量
③编译过程
java编译器先检查泛型的类型然后擦除类型再编译
④泛型使用限制
泛型参数不能传入基本数据类型需要时Object的子类擦除为Object不能用static修饰泛型类中变量或方法泛型但可以在静态方法中加入泛型变为泛型方法。 原因是能否通过类.方法调用。如果是泛型类中的静态成员变量那么调用类.方法仍然确定不了泛型变量。如果是静态方法中加入泛型那么类.方法也可确定泛型变量。区分泛型类中的方法和静态泛型方法 Class PersonT {static T eat(){ }}泛型类中的静态方法不可行 Class PersonT{static k void eat(K a){ }}泛型类中的静态泛型方法可行
⑤代码示例
泛型擦除机制检验
package fanxingtest;import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;public class CaChuTest {public static void main(String[] args) throws Exception{HashSetInteger integers new HashSet();integers.add(1);//得到hashset中的数为1System.out.println(integers.iterator().next());//利用反射插入String类型的数//此时输出1abc故验证泛型是擦除类型的//注意泛型获得方法对象要加入参数add是泛型T的方法运行时擦除为Object类型Class aClass integers.getClass();Method add1 aClass.getDeclaredMethod(add,Object.class);add1.invoke(integers,abc);Iterator iterator integers.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}}
}泛型类的静态方法和静态泛型方法
package fanxingtest;public class StaticFanxinTest {}
class PeopleT{//编译器报错static T data;//编译器报错static T print(){System.out.println(你好);return T t;}//编译器可运行static K void print(K k){System.out.println(你好k);}
}3.通配符是什么作用是什么
①通配符使用与子类泛型不能赋值给父类泛型解决多态不能用于泛型。
ListPeople ListMan 编译不过 子类泛型不能赋值给父类泛型 List ListMan 利用通配符 编译过
②对比
T 声明变量 类或方法 Object泛型擦除不能声明 ? 捕获类型
③通配符的使用
? extends A 赋值A或A的子类 可读不可写子类可能单独的结构? super B 赋值B或B父类 可写可读结构都有注意赋值时通配符在左变量在右注意泛型类型相同类可使用多态
④代码解释
package fanxingtest;import java.util.*;public class TongPeiFuTest {public static void main(String[] args) {//泛型相同类不同为子类父类可以多态HashSetInteger integers new LinkedHashSetInteger();//类相同泛型为子类父类不可以多态,编译出错LinkedHashSetException integers1 new LinkedHashSetRuntimeException();//类相同使用通配符编译过LinkedHashSet? integers2 new LinkedHashSetRuntimeException();//通配符Set? extends HashSet ext null;Set? super HashSet sut null;SetSet c null;SetHashSet d null;SetLinkedHashSet e null;ext c;//编译不过 必须是子类或同级ext d;//编译过ext e;//编译过sut c;//编译过sut d;//编译过sut e;//编译不过必须是父类或同级//可读不可写ext.add(new HashSet());//编译不过Iterator? extends HashSet iterator ext.iterator();iterator.next();//可写可读sut.add(new HashSet());Iterator? super HashSet iterator1 sut.iterator();iterator1.next();}
}
未更新
1.注解是什么有什么用
①注解
注解用于修饰类方法变量提供在编译或运行时使用
②时间
编译器扫描 override 编译器检查是否重写 data 编译器加入代码运行期反射处理 component 通过反射处理具体逻辑处理器
③定义
系统定义注解 override deprecated自定义注解
④元注解注解的注解
Retention 声明生命周期自定义注解一般声明为RuntimeTarget 声明作用的目标Documented 添加信息到文档Inherited 子类自动继承此注解的注解
2.注解的自定义和实现机理是什么
①overide
功能重写的方法JVM在字节码层面实现了该功能
②自定义注解
自定义注解实现注解处理逻辑注解处理器利用反射处理注解javac注册注解处理器为jvm处理器会在运行时运行注解处理器
③代码
注解实现检查年龄大于10的孩子有几个
package annotationtest;import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;public class CheckAgeTest {public static void main(String[] args) {MySchoole mySchoole new MySchoole();try {CheckAge(mySchoole);} catch (Exception e) {e.printStackTrace();}}static void CheckAge(Object o) throws Exception{Class aClass o.getClass();int num 0;Annotation[] annotations aClass.getAnnotations();for(int i 0;i annotations.length;i){if(annotations[i].annotationType()Check.class){Field[] declaredFields aClass.getDeclaredFields();for(int j 0;jdeclaredFields.length;j){if((Integer)declaredFields[j].get(o)10){num;}}}}System.out.println(班级里一共有num个大于10岁的小孩子);}
}Retention(RetentionPolicy.RUNTIME)
interface Check{
}Check
class MySchoole{int age1 11;int age2 13;int age3 9;int age4 12;
}3.JAVA编译过程是什么
解析与填充符号表插入注解处理器并执行注解处理过程分析与字节码的生成
未更新
1.什么是反射反射的用处
①反射
运行时分析类以及执行类的方法通过反射获得任何一个类的所有属性和方法且不知道处理的类是什么Object
②用处
例子不想修改代码只想修改配置例子代码复用写一次注解直接多次使用且方便
③举例
data lombak注解 反射 正常写需要每次添加get set方法 反射写获取注解的类动态添加get set方法生成.class文件properties 配置文件 反射 正常写每次需要直接修改代码 反射写每次只需要修改配置。
④代码
配置反射 动态运行代码
//注意java获取本模块内类的结构用全限定名包名类名且类必须是public类
//此时src/下相当于是类路径即jvm执行class时从类路径下寻找包名类名classnameannotationtest.MyMethod
methodnamesaypackage annotationtest;import java.io.FileInputStream;
import java.lang.reflect.Method;
import java.util.Properties;public class PeiZhiTest {public static void main(String[] args) throws Exception{FileInputStream fileInputStream new FileInputStream(day02/src/annotationtest/method.properties);Properties properties new Properties();properties.load(fileInputStream);String name1 properties.getProperty(classname);String name2 properties.getProperty(methodname);Class aClass Class.forName(name1);Method declaredMethod aClass.getDeclaredMethod(name2);declaredMethod.invoke(aClass.newInstance());}}
class MyMethod{void say(){System.out.println(反射调用方法say);}void walk(){System.out.println(反射调用方法walk);}
}2.反射的结构
①反射
Class类加载到内存的运行时类都有一个Class的实例Class类继承Object类Class实例能表示运行的Object类
②使用的反射
获取Class实例 运行时类的静态属性Class clazz Person.Class; 运行时类的非静态方法 Class clazz Person.getClass; Class类的静态方法 Class clazz Class.forName(“”);创建运行时类的对象 Object o clazz.newInstance();获取运行时类的结构 clazz.getDeclaredMethods();获取具体方法和具体属性对象 Filed age clazz.getDeclareFiled(“age”); age.set(o,12); Method mh clazz.getDeclareMethod(“show”);show.invoke(o);注意 Class的实例不能访问私有结构 Class的实例获得方法时有形参需要加形参不加默认无形参
3.反射在编译和运行时的理解
①多态
Person p new Man() 编译期间允许 运行期间子类方法覆盖父类方法实际上为父类引用指向子类的所有结构
②反射
Object obj clazz.newInstance();method.invoke(obj); 编译期间运行 运行期间obj实际上指向为运行时类的实例
③多态反射
即多态反射可以让父类引用调用子类的私有结构理解父类引用指向的就是子类的类结构重写了方法但是父类引用直接调用子类独有的方法编译不过故可通过反射调用。代码
package reflecttest;import java.lang.reflect.Method;public class FuZiSiYouTest {public static void main(String[] args) throws Exception{Person p new Man();Class aClass p.getClass();Method eat aClass.getDeclaredMethod(eat);//调用成功 结果为子类私有方法eat.invoke(aClass.newInstance());}
}class Person{}
class Man extends Person{void eat(){System.out.println(子类私有方法);}
}④总结
运行时类Class的实例创建的对象都为Object编译过在实际运行时Object指向原本类的结构但不能直接调用因为编译不过需要运行时反射调用编译过
未更新
未更新