Java基础增强(jdk1.5的新特性)

2018-03-03  本文已影响7人  被时光移动的城

本篇文章是在观看学习网络视频《黑马程序员张孝祥javase基础加强》时整理的,作为学习笔记记录下来,如有意见或建议欢迎指出。如转载,请注明出处。谢谢!

1)静态导入

2)可变参数

A 只能出现在可变参数列表最后;
B ...位于变量类型和变量名之间,前后有无空格都可以;
C 调用可变参数和方法时,编译器为该可变参数隐含创建一个数组,再方法体中以数组的形式访问可变参数

3)增强for循环

A 语法

for(type变量名:集合变量名){...}

B 注意事项
迭代变量必须再()中定义
集合变量可以是数组或实现了Iterable接口的集合类
C 实例

   public int add(int x,int... args){
        int sum = x;
        //增强for循环
        for(int arg:args){
            sum += arg;
        }
        return sum;
    }

4)基本数据类型的自动拆箱与装箱

一个字节内,-128-127 ,享元设计模式flyweight(如果很多很小的对象,他们有很多相同的东西,就可以把他们变成一个对象,不同的东西变成外部属性,作为方法的参数传入。外部属性称为外部状态,内部属性成为内部状态)

Interger x = 11;
Interger y = 11;
System.out.println(x==y);//true
Interger a = 150;
Interger b = 150;
System.out.println(a==b);//false

5)枚举

枚举就相当于一个类,其中也可以定义构造方法、成员变量、普通方法和抽象方法。
枚举元素必须位于枚举体中的最开始的部分,枚举元素列表的后要有分号与其他成员分隔。把枚举中的成员方法或变量等放在枚举元素的前面,编译器报错。

A 枚举中常用的方法

枚举api.png
  int length = Enumtest.values().length;//集合长度

B 实现带有构造方法的枚举
构造方法必须是private;

Enumtest enumtest = Enumtest.RED;
public enum  Enumtest {
    RED,//无参
    GREEN(),//无参
    YELLOW(1);//有参,参数随意填写
    private Enumtest(){
        Log.e("TAG","无参构造方法");
    };
    private Enumtest(int i){
        Log.e("TAG","有参构造方法");
    };
}
运行结果图.png
看可以发现,枚举在实例话对象的时候,会把内部所有的对象都实例化一遍。默认调用无参构造,若想有参的构造方法,则在成员()内加入参数;
枚举元素 GREEN,GREEN()一样,都是调用默认的构造方法。
C 带有抽象方法的枚举
Enumtest enumtest = Enumtest.RED;
Log.e("TAG",""+ enumtest.nextLight());
public enum  Enumtest {
    RED {
        @Override
        public Enumtest nextLight() {
            return GREEN;
        }
    },
    GREEN() {
        @Override
        public Enumtest nextLight() {
            return YELLOW;
        }
    },
    YELLOW(1) {
        @Override
        public Enumtest nextLight() {
            return RED;
        }
    };
    private Enumtest(){
        Log.e("TAG","无参构造方法");
    };
    private Enumtest(int time){
        this.tiem = time;
        Log.e("TAG","有参构造方法");
    };
    private int tiem;
    //抽象
    public abstract Enumtest nextLight();

}

运行结果:


带抽象方法的枚举.png

D 枚举只有一个成员时,就可以作为一种单例的实现方式;

6)反射(jdk 1.2)

A 得到各个字节码对应的实例对象(Class类型)

public static void main(String[] args) throws ClassNotFoundException {
        String str1 = "abd";
        Class cls1 = str1.getClass();
        Class cls2 = String.class;
        Class cls3 = Class.forName("java.lang.String");
        System.out.println(cls1==cls1);
        System.out.println(cls1==cls3);
    }

运行结果:

运行结果.png
从运行结果可以看出,三个引用变量指向同一份字节码,虚拟机只会一份字节码。
Class.forName()的作用?
作用是返回字节码,返回的方式有两种,一种情况是这份字节码已经被java虚拟机被加载过(缓存起来),则直接返回;另一种情况是java虚拟机没有加载过,则用类加载器去加载,把加载过的字节码缓存到虚拟机中,以后要得到这份字节码就不需要再次加载了。
B 九个预定义Class实例对象
api图.png
int.class == Interger.TYPE;//true

C 数组类型的Class对象

Class.isArray();

总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如 int[] , void...
D 什么是反射
反射就是把Java类中的各个成分映射成相应的java类。
E 构造方法的反射应用
Constructor类代表某个类中的一个构造方法
得到所有的构造方法getConstructors():

//例子,两种结果相同
 Constructor[] Constructor1 = String.class.getConstructors();
 Constructor[] Constructor2 = Class.forName("java.lang.String").getConstructors();

得到某个构造方法
获得方法时要用类型

//例子
   Constructor<?> constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);

创建实例对象
调用获得的方法时要用到上面相同类型的实例对象

通常方式:String str = new String("abc");

反射方式:String str =  Class.forName("java.lang.String").getConstructor().newInstance(new StringBuffer("abc"));

Class.newInstancee()方法:

   //例子:
   //通过反射实现  new String(new StringBuffer("abc));
        Constructor<?> constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);
        String abc = (String) constructor.newInstance(new StringBuffer("abc"));
        System.out.println(abc);

运行结果:


Constructor事例.png

F 成员变量的反射(Field类)
Field类代表某个类中的一个成员变量

//定义一个类
class ReflectPoint{
        private int x;
        public int y;

        public ReflectPoint(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }
//反射获取
        ReflectPoint mReflectPoint = new ReflectPoint(3,5);//初始化
        Field fieldy = mReflectPoint.getClass().getField("y");//获取fieldy
        //filed值是多少?是5,错!field不是对象身上的变量,而是类上,要用它去取某个对象对应的值
        //很多对象身上都有fieldy,那么到哪个对象身上去取呢,那就传入哪个对象
        System.out.println(fieldy.get(mReflectPoint));
        //获取不可见(private等)变量
        Field fieldx = mReflectPoint.getClass().getDeclaredField("x");
        //暴力反射,不然fieldx.get(mReflectPoint)会报 java.lang.IllegalAccessException异常
        fieldx.setAccessible(true);
        System.out.println(fieldx.get(mReflectPoint));

运行结果:


运行结果.png

获取字段类型obj.getClass().getField().getType();

因为字节码只有一份,所以同一份字节码的对比应用”==“而不是equals
练习:将任意一个对象中的所有String类型真的成员变量对应的字符串内容中的”b“改成”--A--“

//类
public class RPoint {
    private int x;
    public int y;
    public String str1;
    public String str2;
    public String str3;

    public RPoint(int x, int y, String str1, String str2, String str3) {
        this.x = x;
        this.y = y;
        this.str1 = str1;
        this.str2 = str2;
        this.str3 = str3;
    }

    @Override
    public String toString() {
        return "RPoint{" +
                "x=" + x +
                ", y=" + y +
                ", str1='" + str1 + '\'' +
                ", str2='" + str2 + '\'' +
                ", str3='" + str3 + '\'' +
                '}';
    }
}
//-----------------------------------------------------------------
//替换
 public static void main(String[] args) throws Exception {
        RPoint rPoint = new RPoint(3, 5,"abcdb","adkfl","有b哈哈b嗝");//实例化对象
        Field[] fields = rPoint.getClass().getFields();
        for(Field field:fields){
            //字节码只有一份,所以用==会比equals更好一些
            if(field.getType()==String.class){
                String oldS = (String) field.get(rPoint);//field.get();
                String newS = oldS.replace("b","--A--");
                field.set(rPoint,newS);//field.set();
            }
        }
        System.out.println(rPoint);
    }

运行结果:


练习运算结果.png

G 成员方法反射(Method类
Method类代表某个类中的一个成员方法
得到类中的一个方法:

Method methodCharAt = String.class.getMethod("charAt",int.class);
调用方法
通常方式:str.charAt(1);
反射方式:charAt.invoke(str1,1);
如果传递给Method对象的invoke()方法的一个参数为null,说明Method对象对应的是一个静态方法

实例:

        String str1 = "abc";
        //str1.charAt(1)
        Method methodCharAt = String.class.getMethod("charAt",int.class);//方法名,参数(可变参数)
        //methodCharAt.invoke(str1,1);(哪一个对象,传参)
        System.out.println(methodCharAt.invoke(str1,1));

invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。

运行结果:


实例运行结果.png

H 对接收数组参数的成员方法进行反射
实例:用反射的方式执行某个类中的main方法

《 黑马程序员张孝祥JavaSE基础加强》视频中图.png
args[0]就是要启动的class的name
《黑马程序员张孝祥JavaSE基础加强》视频中图.png

I
J
K
L
M
N
O

7)ArrayList和HashSet的比较及Hashcode分析

8)注解

9)泛型

10)java的动态代理

上一篇下一篇

猜你喜欢

热点阅读