----------------------android培训、java培训、期待与您交流! ------------------
今天做的练习不多主要学习java的新特性和反射(反射不是jav新特性),因为昨晚睡得太晚了,早上起来昏昏沉沉的看了几个视频,中午师傅来修热水器,耽搁了挺多时间的,最后还没修成,下午3点小睡了一个小时,晚上9点半的时候又睡了了1.5个小时 11点爬起来在论坛看看,发表了2个问题,顺便看看有自己可以解决的问题吗,同学都懂ssh,内存的东西,压力哦
1,自动拆装箱,和享元模式
基本数据(Primitive)类型的自动装箱(autoboxing)、拆箱(unboxing)是自J2SE 5.0开始提供的功能。虽然为打包基本数据类型提供了方便,但提供方便的同时表示隐藏了细节,建议在能够区分基本数据类型与对象的差别时再使用。
1.对两个包装类对象进行==比较时,比较的是对象的内存地址,而不是包装类所封装的基本类型数据的值,于是
Integer i1 = new Integer(20);
Integer i2 = new Integer(20);
system.out.println(i1==i2);//false
Integer in1=15;
Integer in2=15;
Integer i3=148;
Integer i4=148;
System.out.println(in1==in2);//true
System.out.println(i3==i4);//false
为什么in1和in2是true对于-128-127默认为常用的数值所以基本的类型的整数在一个字节之内即-128~127一旦要装箱就缓冲在池里
下次如果要装箱会看池里有没有,如果有就直接从池里拿出来,就节省内存空间默认小的整数使用率会很高,于是就有 in1==in2为true,i3==i4已经超出了128范围了,这种模式叫做叫做享元模式(flyWeight)就是对象很小,却有很多个这样的小的对象他们有很多属性相同把他们变成一个对象不同的属性变成外部的属性变成方法的参数传入称之为外部状态相同的属性叫做内部状态,小整数是同一个对象,大整数是不同的对象
2,静态导入
import static java.lang.Math.*;
在Math这个静态类中如果我们要使用里面的方法如Math.max(5, 4),但是每次都要Math开头就麻烦了我们就通过静态导入
import static java.lang.Math.*;直接使用math(5,4);
3,枚举一个特殊的类
为什么用枚举,要定义星期几或性别,怎么定义?假设1-7分别表示星期一到星期日,但有的人可能会写成int weekday=0;枚举就是让某个类型的变量的取值只能为固定值中的一个,否则,编译器就会报错。枚举可以让编辑器在编译源程序时就可以控制源程序中填入的非法值,普通变量的方式在开发阶段无法实现这一目标,可以使用一个普通类实现枚举功能,私有的构造方法,1每个元素分别用一个公有的静态成员变量表示, 2可以若干个公有方法或抽象方法,采用抽象方法定义的nextDay就将大量的ifElse转移了一个个独立的类枚举类的基本应用,public enum WeekDay枚举类的所有元素必须在所有成分之前 构造方法必须私有 里面的成员变量相当于是静态的,一个成员的时候,可以看成是单例模式
总结为:
枚举类对象的属性不应允许被改动,所以应该使用 private final修饰
枚举类的使用 private final修饰的属性应该在构造器中为其赋值
若枚举类显式的定义了带参数的构造器,则在列出枚举值时也必须对应的传入参数
用普通类来模拟枚举就会很容易的明白枚举了
/*、
* 模拟枚举/将构造方法私有化别人就没法创建对象 人家使用的时候只能使用里面创建的对象 或者常量
*/
public class WeekDay
{
private WeekDay(){};
public static final WeekDay SUN=new WeekDay();
public static final WeekDay MON=new WeekDay();
public WeekDay nexDay()
{
if(this==SUN)
return MON;
else return SUN;
}
@Override
public String toString()
{
return this==SUN?"SUN":"MON";
}
}
当别人想创建对象的时候只能使用我们已经限制的对象WeekDaysun=WeekDay.SUN;
4,枚举的创建
public enum WeekDay
{
SUN(2),MON,TUE,WED,THI,FRI,SAT;
private WeekDay(){};
private WeekDay(int i){};
}
其中构造方法默认选择但是无参的构造方法如果要选择有参构造就指定参数SUN(2),SUN(2)类似于普通类中WeekDay SUN=new WeekDay(2)
枚举类中添加抽象方法然后每个成员就要实现它的抽象方法如:通过匿名内部类去实现
public enum TrafficLamp
{
RED(45) {
@Override
public TrafficLamp nextLamp()
{
return GREEN;
}
} ,GREEN (50){
@Override
public TrafficLamp nextLamp()
{
return YELLO;
}
},YELLO(10) {
@Override
public TrafficLamp nextLamp()
{
return RED;
}
};
public abstract TrafficLamp nextLamp();
private int time;
private TrafficLamp(int time )
{
this.time=time;
}
}
5,反射
反射不属于jdk的新特性可以理解为将java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获取得其中的变量,方法,构造方法,修饰符,包等信息。这些信息就是用相应类的实例对象来表示,他们是Field,Method,Contructor,Package等等
反射常见方法,Class.forName("Person.class");加载字节码,
对象.getClass();例如new Data().getClass();
Class.forName("类名");Class.forName("java.lang.String")这个比较常用,框架的时候,从网页传入一个字符串
数组也是一种类型 isArray();数组类型的实例对象 Class,isArray();
总之,只要是源程序中出现的类型,都有各自的Class实例对像
Class类代表Java类,它的各个实例对象又分别对应什么呢?
对应各个类在内存中的字节码,例如,Person类的字节码,ArrayList类的字节码,等等。
一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以它们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型
类被加载后,系统都会为该类生成一个对应的 Class对象, 通过该 Class 对象就可以访问到 JVM中的这个类
程序中获得 Class对象通常有如下三种方式:
使用 Class的 forName()静态方法
调用某个类的 class属性(无须调用方法,性能更好)
调用某个对象的 getClass()方法
通过反射来生成对象有如下两种方式:
1使用 Class对象的 newInstance() 方法来创建 Class对象对应类的实例,这种方式要求该 Class对象的对应类有默认的构造器,而执行 newInstance()方法时实际上时利用默认的构造器来创建该类的实例
2先使用 Class对象获取指定的 Constructor对象, 再调用 Constructor 对象的 newInstance() 方法来创建该Class 对象对应类的实例. 通过这种方式可以选择使用某个类的指定的构造器来创建实例一般都使用这个比较多
使用反射调用方法
当获取某个类对应的 Class对象后, 就可以通过 Class 对象的 getMethods() 或 getMethod() 方法来获取全部方法或指定的方法.
l每个 Method对象对应一个方法, 获得 Method 对象后,程序就可通过该 Method来调用对应方法. 在 Mthod 里包含一个 invoke()方法
l通过 Class对象的 getFields()或 getField()方法可以获取该类所包括的全部 Field或指定的 Field
lFiled通过如下两组方法来访问属性
getXXX(Objectobj)
setXXX(Objectobj, Xxx val);
---------------------- android培训、java培训、期待与您交流! ------------------