泛型
- 泛型,参数化类型,分为泛型类、接口、方法
泛型类
class 类名称 <泛型标识> {
private 泛型标识 var;
...
}
泛型接口
public class chabug {
public static void main(String[] args) {
new testa().next();
}
}
interface test<T>{
public T next();
}
class testa implements test<String>{
private String[] b = new String[]{"a","b","c","d"};
@Override
public String next(){
Random rand = new Random();
System.out.println(b[rand.nextInt(3)]);
return null;
}
}
泛型方法
public class chabug {
public static void main(String[] args) {
out("28");
out("永远滴神");
}
public static <T> void out(T t) {
System.out.println(t);
}
}
泛型通配符
public void showKeyValue1(Generic<?> obj){
Log.d("泛型测试","key value is " + obj.getKey());
}
泛型上下边界
- 在使用泛型的时候,我们还可以为传入的泛型类型实参进行上下边界的限制,如:类型实参只准传入某种类型的父类或某种类型的子类。为泛型添加上边界,即传入的类型实参必须是指定类型的子类型,泛型的上下边界添加,必须与泛型的声明在一起.
-
常规例子(会提示类型无法转换)
- 使用上下边界
- 疑惑
GenericHolder<Fruit> fruitHolder = new GenericHolder<Fruit>()
为何意思
解决:
Fruit fruit = new Fruit("水果");
fruitHolder.setObj(fruit)
先实例化再传入对象,参考如下:
泛型数组
- 不可以
List<String>[] ls = new ArrayList<String>[10];
- 可以
List<?>[] ls = new ArrayList<?>[10];
List<String>[] ls = new ArrayList[10];
代理
静态代理
抽象角色:一般会使用接口或抽象类来解决
真实角色:被代理的角色
代理角色:代理真实角色后,我们一般会做一些附属操作
客户:访问代理对象的人
- 抽象角色
//接口——》租房
public interface Rent {
public void rent();
}
- 真实角色
//真实角色->房东
public class Host implements Rent{
@Override
public void rent(){
System.out.println("房东要出租房子");
}
}
- 代理角色
package ChaBugStudy;
public class Proxy implements Rent{
private Host host;
public Proxy(){
}
public Proxy(Host host){
this.host = host;
}
public void rent(){
seeHouse();
host.rent();
hetong();
fare();
}
//看房
public void seeHouse(){
System.out.println("中介带你看房");
}
public void hetong(){
System.out.println("签合同吧!");
}
//收中介费
public void fare(){
System.out.println("这房子不错,阔绰的你决定给点小费");
}
}
- 客户端访问代理角色
public class Clinet {
public static void main(String[] args) {
Host host = new Host();
Proxy proxy = new Proxy(host);
proxy.rent();
}
}
- 运行一下看看效果
- 缺点
一个真实对象需要产生一个代理
动态代理(先留着看完反射再看)
- 动态代理(这里是基于JDK动态代理)
一个动态代理类可以代理多个类,只要是实现了同一个接口
- 抽象角色
public interface Rent {
public void rent();
}
- 真实角色
public class Host implements Rent{
public void rent(){
System.out.println("房东要出租房子!");
}
}
- 代理角色
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Proxyhandler implements InvocationHandler {
//被代理的接口
Rent rent;
public void setRent(Rent rent){
this.rent = rent;
}
//生成得到代理类
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
}
// 处理代理实例,并返回结果
public Object invoke(Object proxy, Method method,Object[] args) throws Throwable{
Object result = method.invoke(rent,args);
return result;
}
}
- 客户端(客户)角色
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class Clent {
public static void main(String[] args) {
//真实角色
Host host = new Host();
//代理角色
Proxyhandler pih = new Proxyhandler();
//通过调用程序处理角色来处理要调用的接口角色
pih.setRent(host);
Rent proxy = (Rent) pih.getProxy();
proxy.rent();
}
}
注解(Java.Annotation)
- 格式
@注释名
- 内置注解
@Override
定义在java.lang.Override中,表示重写
Deprecated
定义在java.lang.Deprecated中,表示废弃,不鼓励使用,使用时会多一条横线,但依旧可以使用
@SuppressWarnings
定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息
使用前
使用后
元注解
- 作用
注解其他注解
- @Target(用于描述注解的使用范围)
@MYAnnotation
public class ZhuJie {
@MYAnnotation
public static void main(String[] args) {
}
}
//METHOD 方法、TYPE 类
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@interface MYAnnotation{
}
- @Retention(表示需要在什么级别保存该注释信息,用来描述注解的生命周期(SOURCE < CLASS < RUNTime))
@Retention(value = RetentionPolicy.RUNTIME)
- @Document(说明该注释将被包含在javadoc中)
- @Inherited(说明该子类可以继承父类中的该注解)
自定义注解
- @interface(自定义注解关键字)
-
格式
public @interface 注解名{定义内容}
- 自定义注解
package ChaBugStudy;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Syst1m(Team = "ChaBUg",Founder = "Y4er",brother = "syle")
public class ZhuJie {
@Syst1m
public static void main(String[] args) {
System.out.println("ChaBug.Org");
}
}
@Target(value = {ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface Syst1m{
String Team() default "ChaBug";
String Founder() default "Y4er";
String brother() default "Syle";
}
反射(Reflection)
- 正常方式
引入需要的“包类”名称-)通过new实例化-〉取得实例化对象
- 反射方式
实例化对象->getclass()方法->取得完整的“包类”名称
- 优缺点
可以实现动态创建对象和编译,体现出很大的灵活性。
对性能有影响,慢于直接操作
- 主要API
java.lang.class 代表一个类
java.lang.reflect.Method 代表类的方法
java.lang.reflect.Field 代表类的成员变量
java.lang.reflect.Constructor 代表类的构造器
- 获取class类的几种方式
常用方法
package ChaBugStudy;
public class Reflection {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Student();
//方式一:通过对象获得
Class c1 = person.getClass();
System.out.println(c1.hashCode());
//方式二:forname获得
Class c2 = Class.forName("ChaBugStudy.Person");
System.out.println(c2.hashCode());
//方式三 通过类名.class
Class c3 = Person.class;
System.out.println(c3.hashCode());
//方式四 内置类型的包装类
Class c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//获取父类
Class c5 = c1.getSuperclass();
System.out.println(c5.hashCode());
}
}
class Person{
String name;
public Person(){
}
public Person(String name){
}
@Override
public String toString(){
return name;
}
}
class Student extends Person{
public Student(){
this.name = "学生";
}
}
class Teacher extends Person{
public Teacher(){
this.name = "老师";
}
}
- 哪些类型可以有Class对象
**
class
interface接口
[]数组
enum枚举
注解@interface
基本数据类型
void
**
Class c1 = Object c1 = Object.class; //类
Class c2 = Comparable.class; //接口
Class c3 = String[].class; //数组
Class c4 = Override.class; //注解
Class c5= ElementType.class; // 枚举
Class c6 = Integer.class; // 基本数据
Class c7 = void.class; //void
Class c8 = Class.class; //CLass
- 获取运行时类的完整结构
获取类的名字
c1.getName() 获取包名加类名
c1.getSimpleName() 获得类名
获得类的属性
Field[] field = c1.getFields() 只能获取public属性
fields = c1.getDeclaredFields() 找到全部的属性
获得指定属性的值
Field name = c1.getDeclaredField("name")
获得类的方法
Method[] methods = c1.getMethods(); 获得本类以及父类的全部public方法
methods = c1.getDeclaredMethods(); 获得本类的所有方法
获得指定方法
Method getname = c1.getMethod("getname",null)
Method serName = c1.getMethod("setname",String.class)
获得构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor:constructors){
System.out.println(construcior)}
constructors = c1.getDeclaredConstructors();
获得指定构造器
c1.getDeclaredConstructor(String.class,int.class)
- 动态创建对象执行方法
获得对象
Class c1 = Class.forname("XXX")
构造对象
User user = (User) c1.nerInstance(); 无参构造器
通过构造器创建对象
Constructor constructor = c1.getDeclaredConstructor(String.class)
User user2 = (USer)constructor.nerInstance("Syst1m")
反射调用普通方法
User user3 = (User)c1.nerInstance();
Method serName = c1.getDeclaredMethod("setName",Strind.class);
setName.invoke(User3,"syst1m");
反射操作属性
不能直接操作私有属性,需要关闭安全检测
User user4 = (User)c1.nerInstance();
Field name = c1.getDeclaredFields();
name.setAccessible(true) //关闭权限检测
name.set(User4,"syst1m");
- 参考
https://blog.csdn.net/lililuni/article/details/83449088
原创文章,作者:syst1m,未经授权禁止转载!如若转载,请联系作者:syst1m