http://blog.csdn.net/dgy5258565/article/details/17399631
http://blog.csdn.net/dgy5258565/article/details/17539179
数组的内存结构
Java程序在运行时,需要在内存中的分配空间。为了提高运算效率,有对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。
栈内存:用于存储局部变量,当数据使用完,所占空间会自动释放。
堆内存:
(1)数组和对象,通过new建立的实例都存放在堆内存中。
(2)每一个实体都有内存地址值
(3)实体中的变量都有默认初始化值
(4)实体不在被使用,会在不确定的时间内被垃圾回收器回收
数组常见操作
选择排序:
public class test {
public static void main(String[] args) {
int arr[]={2,4,5,1,3};
int max;
//外循环进行元素顺序调换
//内循环获得每趟中部分数组中的最大元素下标
for(int i=1;i<arr.length;i++){
max=0;
for(int j=1;j<=arr.length-i;j++){
if(arr[j]>arr[max]){
max=j;
}
int temp=arr[arr.length-i];//将此趟的部分数组的最后一个元素值存入temp
arr[arr.length-i]=arr[max];//将此趟的部分数组的最大元素值存入最后元素的位置
arr[max]=temp;//将temp中的值放入之前最大元素的位置上。
}
}
//遍历输出
for(int i:arr){
System.out.println(i);
}
}
}
for(int i=1;i<arr.length;i++){
for(int j=0;j<arr.length-i;j++){
if(arr[j]>arr[j+1]){
/*相邻元素进行比较,若较前元素大于较后元素,
* 将其调转位置
* */
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
当函数内需要用到调用该函数的对象时,就用this来表示这个对象。即但凡本类功能内部使用到了本类对象,就都用this表示。
构造方法的重载
* A:当在描述事物时,要不要在类中写构造方法呢?这时要根据描述事物的特点来确定,当描述的事物在创建其对象时就要明确属性的值,这时就需要在定义类的时候书写带参数的构造方法。
* 若创建对象时不需要明确具体的数据,这时可以不用书写构造方法(不书写也有默认的构造方法)。
* 构造方法和一般方法区别
* A: 目前为止,学习两种方法,分别为构造方法和一般方法,那么他们之间有什么异同呢?
1.格式不同
构造方法 : 修饰符 类名(参数类型 参数 …){
初始化成员变量
}
一般方法: 需要有返回值类型
2.作用不同
构造方法一般用来给成员变量初始化;
一般方法根据需求而定;
3.调用方式不同
构造方法创建对象时调用, 或者this() super() 语句调用
普通方法需要对象调用或者静态方法直接调用静态方法.
4.执行不同
构造方法在对象创建时就执行了,而且只执行一次。
一般方法是在对象创建后,需要使用时才被对象调用,并可以被多次调用。
this语句:用于构造函数间互相调用。this();
this()语句只能定义在构造函数的第一行。因为初始化要先执行。
this代表其所在函数所属对象的引用。即this代表本类对象的引用。简单说,哪个对象在调用this所在的函数,this就代表哪个对象
http://blog.csdn.net/dgy5258565/article/details/17539179
一、静态(static)
1、static关键字
当成员被静态修饰后,就多了一种调用方式,除了被对象调用外,还可以直接被类名调用。格式:类名.静态成员
被static修饰后的成员具备以下特点:
(1)随着类的加载而加载(随着类的消失而消失,说明静态的生命周期最长)(放在方法去,周期很长。先加载后消亡)
(2)优先于对象存在(静态先存在,对象后存在)
(3)被所有对象所共享
(4)可以直接被类名调用
注意:(1)静态方法只能访问静态成员(非静态方法既可以访问静态也可以访问非静态。)
(2)静态方法中不可以写this,super关键字(因为静态优先于对象存在,所以静态方法中不可以出现this)
(3)主函数是静态的
什么时候定义静态变量?
当对象中出现共享数据时,该数据被静态所修饰,对象中的特有数据要定义成非静态存在于堆内存中。
注意:
接口中的每个成员变量都默认使用public static final修饰。
所有接口中的成员变量已是静态常量,由于接口没有构造方法,所以必须显示赋值。可以直接用接口名访问。
interface Inter {
public static final int COUNT = 100;
}
访问接口中的静态变量
Inter.COUNT
//
final的特点
final修饰类不可以被继承,但是可以继承其他类。
final**修饰的变量**称为常量,这些变量只能赋值一次。
final int i = 20;
引用类型的变量值为对象地址值,地址值不能更改,但是地址内的对象属性值可以修改。
final Person p = new Person();
Person p2 = new Person();
p = p2; //final修饰的变量p,所记录的地址值不能改变
p.name = “小明”;//可以更改p对象中name属性值
p不能为别的对象,而p对象中的name或age属性值可更改。
修饰成员变量,需要在创建对象前赋值,否则报错。(当没有显式赋值时,多个构造方法的均需要为其赋值。)
class Demo {
//直接赋值
final int m = 100;
//final修饰的成员变量,需要在创建对象前赋值,否则报错。
final int n;
public Demo(){
//可以在创建对象时所调用的构造方法中,为变量n赋值
n = 2016;
}
}
对象的初始化过程:
Person p = new Person(“zhangsan”,20);
该语句做了什么事情?
对象的初始化过程:
1、因为new用到了Person.class,所以会先找到Person.class文件并加载到内存中。(new Person();)
2、执行该类中的静态代码块,如果有的话,给Person.class类进行初始化。
3、在堆内存中开辟空间,分配内存地址。(例如内存中开辟了空间,分配地址为0x0023)
4、在堆内存中建立对象的特有属性,并进行默认初始化。(建立特有属性name和age,默认初始化:name=null;age=0;)
5、对属性进行显示初始化。(类中定义属性的时候已经有显示的定义值,例:private String name=”lisi”。则对属性显示初始化:name=”lisi”,age=0)
6、对对象进行构造代码块初始化。
7、对对象进行对应的构造函数初始化。(进行构造函数初始化:name=”zhangsan”,age=20)
8、将内存地址赋给栈内存中的p变量。(将内存地址0x0023赋给p,则p指向对象Person(“zhangsan”,20))
饿汉式:类一进入内存就建立了对象,即在类中就先初始化对象。
单例设计模式使用:
对于事物该怎么描述,还怎么描述。
当需要该事物的对象保证在内存中唯一时,就将以上的三步加上即可。
class Single{
private Single(){}//私有化构造函数,禁止其他程序建立本类对象。
private static Single s=new Single();//在类中创建一个本类对象,对其进行静态私有修饰。
public static Single getInstance(){
return s;
}//向外提供本类对象。
}
public class SingleDmo {
public static void main(String[] args) {
Single ss=Single.getInstance();//获得Single类类型的对象。
Single s1=Single.getInstance();//s1和ss都是同一个对象。
}
}
class Single{
private int num;
public void setNum(int num){
this.num=num;
}
public int getNum(){
return num;
}
private Single(){}//私有化构造函数,禁止其他程序建立本类对象。
private static Single s=new Single();//在类中创建一个本类对象,对其进行静态私有修饰。
public static Single getInstance(){
return s;
}//向外提供本类对象。
}
//创建对象得到限制?
public class SingleDmo {
public static void main(String[] args) {
Single s1=Single.getInstance();//获得Single类类型的对象。
Single s2=Single.getInstance();//s1和s2都是同一个对象。
//分别赋两个值
s1.setNum(5);
s2.setNum(6);
//输出的都是6.因为两个对象其实都是一个对象,先给对象中num赋的5被后来的6覆盖了。
System.out.println("s1:"+s1.getNum());
System.out.println("s2:"+s2.getNum());
}
}
class Single{
private Single(){}
private static Single s=new Single();//**先初始化**对象
public static Single getInstance(){
return s;
}//向外提供本类对象。
}
懒汉式出现问题:
例如A程序和B程序,A程序判断完s==null,cpu切换到另一程序,A程序挂起;接着cpu开始执行B程序,B程序判断完s==null,cpu又切换到另一程序,B程序挂起。等到A程序恢复执行,则建立一个对象s,接下来当B程序开始执行,B又会进行创建对象s,由于这是单例设计,所以这里两个对象会冲突报错,产生安全问题。
这个问题可以用synchronized关键字(同步)来对程序加锁解决(
class Single{
private Single(){}
private static Single s=null;
public static Single getInstance(){
if(s==null){
synchronized(Single.class){
if(s==null){
s=new Single();
return s;
}
}
}
}//向外提供本类对象。
}