您的位置:首页 > 职场人生

黑马程序员-------笔记整理(高薪课程二)

2012-05-24 02:27 309 查看
----------------------android培训java培训、期待与您交流! ----------------------

今儿一天过的有点扯淡,啥也没做成,一大早让人给叫出去办事,等我到了地方给他打电话的时候才发现他电话停机。我圈圈叉叉诅咒呢。。。回来的时候想去看看别的朋友吧,人家又不想见我。崩溃了。点儿背。晚上睡觉的时候还让人给开刷。啥事了。算了吧,不想了。整理一下今天看的东西吧,睡觉觉。困得难受。今儿就不列大纲了,等有时间给补上吧。眼睛睁不开了。

1.Person p1 = new Person();

p1.getClasss();//p1代表某个字节码所产生的对象。通过getClass可以得到它所属的字节码。

2.Class.forName(“java.lang.String”);//得到string类的字节码。第一种是这个类的字节码已经加载进内存,不需要再加载,直接找到该字节码并返回。第二种是这个类的
字节码还没有被加载进内存,先使用类加载器将该类加载进内存,将该字节码缓存,并返回得到的字节码。

3.八个基本数据类分别对应8个基本类型的字节码文件。还有一个void。

Class clazz =void.class;

总结一下:任何对象都具有.class属性。

Demo:

Stringstr = “abc”;

Classcls1 = str.getClass(); //得到stri所属的字节码

Classcls2 = String.class(); //得到String类的字节码

Classcls3 = Class.forName(“java.lang.String”);//通过forName得到String类字节码

System.out.print(cls1==cls2);

System.out.print(cls1==cls3);

打印结果两个true,证明了不管通过什么方式得到该类的字节码文件,该字节码文件只有一个。

4. 方法:

a) isPrimitive() 是否是基本数据类型 cls2.isPrimitive();

b) 注意:int.class = Integer.TYPE 这个常量代表了这个包装类所包装的基本数据类型的字节码

c) 判断一个字节码文件是不是数组类型,可以使用isArray()方法.int[].class.isArray().

5. 反射:

a) 构造函数的反射:

i. Constructor类代表字节码文件中的构造方法

ii. Constructor cons =String.class.getConstructor(StringBuffer.class);

1. //剖析:

a) String.class 得到String类的字节码文件

b) getConstructor()得到构造函数

                getConstructor

(Class<?>... parameterTypes)

c) StringBuffer.class 传入的是对应参数的字节码文件,每一个类型对应的字节码文件都是唯一的。这个stringbuffer表示选择哪个构造器

i.扩展…代表的是可变参数,也就是说可以传入多个参数

d) Constructor 返回的类型是构造函数,所以拿Constructor来接收

扩展:

i.new String(new StringBuffer(“abc”));

1.剖析:

i.new StringBuffer(“abc”) //创建一个匿名对象,它的初始内容是abc。

ii. new String() 创建一个匿名对象,它传入的参数是stringbuffer类型的数据

iii. cons.newInstance(newStringBuffer(“abc”))

1. 剖析

a) 在上边得到了构造函数,使用newInstance()来创建构造函数实例化对象,每调用一次,就相当于创建了一个String对象

b) new StringBuffer(“abc”)传入一个stringbuffer的对象,表示的是使用这个构造方法的时候需要给里边传入一个stringbuffer的对象(详见扩展)

iv.String str =(String)cons.newInstance(new StringBuffer(“abc”));

1. 注意;这里需要强转一下,因为编译器在编译时只认识它是一个构造方法,但是不明确究竟是谁的构造方法,所以这里需要强转明确一下。

v. System.out.print(str.charAt(2)); //返回该参数的第二个位置的数据

整理:整个意思是是先获取到某个类的构造方法,然后通过创建构造方法的实例化对象,通过传入相对应的对象,返回一个值。

b) 成员变量的反射

public
class
ReflectPoint {
//申明两个变量,对X,Y进行反射
private
int
x;
public
int
y;
//构造函数
public ReflectPoint(int x,
int y) {
super();
this.x = x;
this.y = y;
}
}

public
static void
main(String[]args)
throws SecurityException, NoSuchFieldException {
ReflectPoint pt1 =new ReflectPoint(3, 5);

//创建一个对象,对其进行默认赋值
Field fildy =pt1.getClass().getField("y");

//根据变量名,返回一个类中的公共的成员变量,此时fildy只代表一个变量 ,而不是一个值
System.out.print(fildy.get(pt1));
//这时才是获取成员变量y的值.这里需要明确的是它是属于哪个对象的变量。
Field fieldX =pt1.getClass().getDeclaredField(“x”);
//获取私有成员变量
fieldX.setAccessible(true);
//暴力访问.
System.out.print(fieldX.get(pt1));

}

开发应用:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b”变成“a”

public
class
ReflectPoint {
//申明两个变量,对X,Y进行反射
private
int
x;
public
int
y;
public String
str1 = "ball";
public String
str2 = "basketball";
public String
str3 = "fdbas";
//构造函数
public ReflectPoint(int x,
int y) {
super();
this.x = x;
this.y = y;
}
//复写toString方法
@Override
public String toString(){
return
"ReflectPoint [ str1=" + str1
+ ", str2=" +
str2 + ", str3=" +
str3 + "]";
}

}
//字符串转换
public
static void
changeStringValue(Object obj)
throwsIllegalArgumentException, IllegalAccessException {
// TODO Auto-generatedmethod stub
//得到该类中的所有的成员变量
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
//因为字节码只有一份,所以直接使用双等号
//判断变量的类型是否是String类型
if(field.getType()==(String.class)){
//取值
String oldValue =(String)field.get(obj);
//使用字符串替换功能
String newValue = oldValue.replace('b',
'a');
//将原值替换成新值
field.set(obj, newValue);
}
}
}

//打印

System.out.println(pt1);
changeStringValue(pt1);
System.out.println(pt1);

c) 成员函数的反射:

i. Method类

public
static void
getShow(Objectobj)
throws Exception {
Method method = obj.getClass().getMethod("show", int.class);
method.invoke(null, 10);//代表了它调用的是一个静态方法
method.invoke(obj,10); //代表了它调用哪个类里边的函数
}

为什么使用反射调用?

因为源程序中不知道究竟要执行哪个类.

/*
* 写一个程序,这个程序根据用户提供的类名,去执行该类中的main方法
*/
public
static void
main(String[]args)
throws SecurityException, NoSuchMethodException, Exception {
// TODO Auto-generated method stub
StringstartClassInfo = args[0];
//假设传入的参数第一个是类名
Method method= Class.forName(startClassInfo).getMethod("main", String[].class);
//method.invoke(null, (Object)newString[]{"12","34","432"});//因为string[]也属于object类型
method.invoke(null,
new Object[]{new String[]{"12","34","432"}});
//将其封装成Object数组类型的对象,成为一个整体传入.其原因是为了兼容jdk1.4
}

}
class TestArguments{
public
static void
main(String[]args) {
for(String arg :args){
System.out.println(arg);
}
}
}

数组与object的关系:

int[] a1 =
new int[3];
int[] a2 =
new int[4];
int[][] a3 =
new int[2][3];
String[] a4 = new String[3];
System.out.println(a1.getClass() == a2.getClass());
//因为是对象,必须使用方法来获取当前对饮的字节码文件 true
System.out.println(a1.getClass().equals(a3.getClass()));//false
System.out.println(a1.getClass().equals(a4.getClass()));

System.out.println(a1.getClass().getSuperclass().getName()); //[I
System.out.println(a2.getClass().getSuperclass().getName());
System.out.println(a3.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());

//4个打印输出的结果都是Object

}

Object[] obj = a1;//错误,基本数据类型的一维数组不能够转换为Object数组类型

//结论:除基本类型以外的类型 任何对象的父类都是Object。

基本数据类型不是object

----------------------android培训java培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: