泛型

泛型

泛型接口
interface Demo_inter<T>{
    T getVal();
}
class Demo_inter_1<T> implements Demo_inter<T>{

    T val;

    public void setVal(T val) {
        this.val = val;
    }

    @Override
    public T getVal() {
        return val;
    }
}
class  Demo_inter_2 implements Demo_inter<String>{
    String val;
    @Override
    public String getVal() {
        return val;
    }

    public void setVal(String val) {
        this.val = val;
    }
}
    Demo_inter_1<String> di1=new Demo_inter_1<String>();
    di1.setVal("123");
    System.out.println(di1.getVal());

    Demo_inter_2 di2=new Demo_inter_2();
    di2.setVal("234");
    System.out.println(di2.getVal());
泛型方法
public static <T extends Number> _Num<T> get_Num(T t){
        _Num<T> temp=new _Num<T>(t);
        return  temp;
    }

只需要在使用泛型的时候呢,声明一下,然后通过函数的输入决定泛型的类型

泛型数组

我们用可变参数为例子

泛型嵌套
_嵌套_实现<_嵌套_base<Integer,String>> th=new _嵌套_实现<_嵌套_base<Integer,String>>(new _嵌套_base<Integer,String>(12,"asd"));

这里 _嵌套_base<Integer,String> 指定为 _嵌套_实现 的泛型的类型了

枚举

enum Color{
    Red,White,Blue;
}

enum实际上是继承了Enum 构造方法 Enum(String name, int ordinal)
上面的语句实际上就是条用了这个构造方法

     String name() 
              返回此枚举常量的名称,在其枚举声明中对其进行声明。 
     int ordinal() 
              返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。 

Class类

这里用到反射机制,通过实例就可以获得他的类信息
Class类构造方法私有化

实例化方法
  • Class.forName()
  • 类.class
  • 实例.getclass()
class类用来实例化对象

但是对象必须是有无参的构造方法

//Class来实例化对象
        try {
            c c_instance= (c) c1.newInstance();
            c_instance.setName("lz");
            System.out.println(c_instance.toString());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

当没有无参的构造方法的时候

//不存在无参数的构造方法怎么处理
        try {
            Class <?> c4=Class.forName("基础.c1");
            Constructor<?> constructor[]=c4.getConstructors();
            c1 ccc= (基础.c1) constructor[0].newInstance(123);
            System.out.println(ccc.x);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
class获得类的结构

实现的全部接口

        Class<?> inter[]=c5.getInterfaces();
        for (int i = 0; i < inter.length; i++) {
            System.out.println(inter[i].getName());
        }

获得父类

    Class<?> fatther=c5.getSuperclass();
    System.out.println(fatther.getName());

获得构造方法

    Constructor<?>[] constructor=c5.getConstructors();
    StringBuffer sb=new StringBuffer();
    for (int i = 0; i < constructor.length; i++) {
        sb.append(Modifier.toString(constructor[i].getModifiers())+" ");
        sb.append(constructor[i].getName()+"(");

        Class <?> para[]=constructor[i].getParameterTypes();
        for (int j = 0; j < para.length; j++) {
           sb.append(para[j]);
           if(j+1!=para.length){
               sb.append(",");
           }
           else
               sb.append(")");
        }
        System.out.println(sb);
    }

Constructor类,可以单独获得构造方法的修饰符,名称参数等等
Modifier类,指定标识符的类型

获得方法
Method类,取得跟方法有关的相关信息

            Method []declaredMethod=c5.getDeclaredMethods();
            for (int i = 0; i < declaredMethod.length; i++) {
                sb.append(Modifier.toString(declaredMethod[i].getModifiers())+" ");
                sb.append(declaredMethod[i].getName()+"(");
                Class<?>[] para=declaredMethod[i].getParameterTypes();
                for (int j = 0; j < para.length; j++) {
                    sb.append(para[j].getName());
                    if(j+1!=para.length){
                        sb.append(",");
                    }
                }
                sb.append(")");
                System.out.println(sb);
                sb.delete(0,sb.length());
            }

Class.getDeclaredMethods 获得本类中定义的方法
Class.getMethods() 获得所有方法,包括父类中的
获得属性

 Field []field=c5.getDeclaredFields();
利用反射直接调用方法
        Class<?> c6=Class.forName("基础.c");
        Method m1=c6.getMethod("print",String.class);
        m1.invoke(c6.newInstance(),"中国");
        Method m2=c6.getMethod("print",String.class,int.class);
        String ret=(String) m2.invoke(c6.newInstance(),"中国",43);
        System.out.println(ret);

这里调用了invoke函数来执行Method

通过反射改变属性
        Object obj=c6.newInstance();
        Field nameField=c6.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set((c)obj,"lz");
        Field ageField=c6.getDeclaredField("age");
        ageField.setAccessible(true);
        ageField.set((c)obj,12);

这样就不需要set和get方法了,而且对于私有的属性只要setAccessible为true就可以访问修改了
这就是说Class类可以获得一个类中的全部所有的信息,包括创建这个类的实例,并且在这个实例上面去操作属性/方法等

通过反射处理数组

可变参数

 public static void main(String[] args) {

    fun("1223","13","123123");
    fun("w");
    fun(123,"asd","22e");
}

public static void fun(String...args){
    for (int i = 0; i < args.length; i++) {
        System.out.println(args[i]);
    }
}
public static void fun(int x,String...args){
    System.out.println(x);
    for (int i = 0; i < args.length; i++) {
        System.out.println(args[i]);
    }
}

所谓的可变参数就是一个动态的数组,注意

  • 只能有一个参数是可变参数
  • 可变参数必须是参数表的最后一个
  • 注意在重载的时候不要发生冲突,导致jvm不知道应该去执行哪一个函数

区分 正斜杠/ 反斜杠

在java里面 /就是一个普通的字符,作用大概就是注释,文件路径之类
用来转义,因此""才代表一个
转移比较容易理解,但是在正则表达式的应用场合就比较难受,例如

    String s ="sdf\a\aa";
    //把s中的反斜杠 替换为\

方法1

    System.out.println(s.replaceAll("\\", "\\\\"));

这里按照正则表达式处理,"\"首先认为是字符串,实际的值就是"",然后正则表达式转义就是,同理后面的8个就变成了"\"

方法2

    System.out.println(s.replace("\", "\\"));

这里就是简单的模式匹配,没有调用到正则表达式,也就少了一层转义。
就是说如果没有用到正则表达式的话,就没有必要进行两次转义的操作了

Annotation

系统内建的

  • @Override
    • 重写
  • @Deprecated
    • 已经过时
  • @SuppressWarnings()
    • 压制警告

自定义的Annotation

 //无参数的
@interface Annotation01 {}
//有参数
@interface Annotation02{
    public String value();
}
//多参数
@interface Annotation03{
    public String value();
    public String key();
}
//数组
@interface Annotation04{
    public String[] value();
}
//默认值的
@interface Annotation06{
    public String value() default "name";
}
//枚举类型
@interface Annotation07{
    public This value() default This.Blue;
}

调用

@Annotation02("lz");
@Annotation03(key="lz",value="123");
@Annotation04(value={"1","2","3"});
@Annotation07(This.White);

@Retention,用来指定自定义的Annotation的作用范围,修饰Annotation

@Retention(RetentionPolicy.RUNTIME)表示在运行时有效
RetentionPolicy.SOURCE 只对源码有效
RetentionPolicy.CLASS 加载到Class类中

Target,用来指定自定义的Annotation的使用的位置(比如只能在构造方法上使用等)

原文地址:https://www.cnblogs.com/Coder-Pig/p/6513345.html