本篇文章是在观看学习网络视频《黑马程序员张孝祥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 枚举中常用的方法
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","有参构造方法");
};
}
看可以发现,枚举在实例话对象的时候,会把内部所有的对象都实例化一遍。默认调用无参构造,若想有参的构造方法,则在成员()内加入参数;
枚举元素 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();
}
运行结果:
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);
}
运行结果:
从运行结果可以看出,三个引用变量指向同一份字节码,虚拟机只会一份字节码。
Class.forName()的作用?
作用是返回字节码,返回的方式有两种,一种情况是这份字节码已经被java虚拟机被加载过(缓存起来),则直接返回;另一种情况是java虚拟机没有加载过,则用类加载器去加载,把加载过的字节码缓存到虚拟机中,以后要得到这份字节码就不需要再次加载了。
B 九个预定义Class实例对象
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);
运行结果:
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));
运行结果:
获取字段类型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);
}
运行结果:
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 对象表示的底层方法。
运行结果:
H 对接收数组参数的成员方法进行反射
实例:用反射的方式执行某个类中的main方法
args[0]就是要启动的class的name
I
J
K
L
M
N
O