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

                                       ----------------------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培训、期待与您交流! ----------------------  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值