再问 MyClass.class和MyClass.getClass()的区别

weidu23 2013-07-05 09:56:51
原本我以为MyClass.class和MyClass.getClass()是相同的,但是,后来发现不对 !

如下面代码所示 :

import java.io.*;
public class DirList {
public static void main(String[] args) {
File path = new File(
DirList.class.getResource(".").getFile().toString()
);
System.out.println(
DirList.class.getResource(".").getFile().toString()
);
}
}

这个代码无错误 !!!

然后,再看一个

import java.io.*;
public class DirList {
public static void main(String[] args) {
File path = new File(
DirList.class.getResource(".").getFile().toString()
);
System.out.println(
DirList.getClass().getResource(".").getFile().toString()
);
}
}

这个代码,报错!
----------------------
错误提示:
Cannot make a static reference to the non-static method getClass() from the type Object
----------------------

从错误提示来讲,getClass()是一个非静态方法,却被静态类型引用,从而导致错误!
但是," .class " 确不会,也就是说,“ .class ”是一个静态的类型对象 !

问题:
1、我的分析正不正确,望解析 。
2、如果问题1我的分析正确,那么我就想问了,干嘛要定义两个属性不同,功能却一样的类型,这样做有什么用,用在哪里呢 ???
...全文
469 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
weidu23 2013-07-09
  • 打赏
  • 举报
回复
引用 27 楼 lcf 的回复:
Cat的目标是有一个Logger,它产生的过程等同于LoggerFactory.getLogger(Cat.class);。在Animal这个抽象类里面,那一句getClass是根据你实例化的子类来返回不同值的。比如你有Dog extends Animal { },那么new Dog()中的logger就相当于LoggerFactory.getLogger(Dog.class);,而你在Dog类中不需要重复写这一句,因为Animal类中,logger已经被初始化为这个值了(getClass()返回的就是Dog.class)
难怪 ... 明白了 ! 可以结贴了 ... .................
weidu23 2013-07-09
  • 打赏
  • 举报
回复
引用 27 楼 lcf 的回复:
[quote=引用 26 楼 weidu23 的回复:] [quote=引用 16 楼 lcf 的回复:] Cat的目标是有一个Logger,它产生的过程等同于LoggerFactory.getLogger(Cat.class);。在Animal这个抽象类里面,那一句getClass是根据你实例化的子类来返回不同值的。比如你有Dog extends Animal { },那么new Dog()中的logger就相当于LoggerFactory.getLogger(Dog.class);,而你在Dog类中不需要重复写这一句,因为Animal类中,logger已经被初始化为这个值了(getClass()返回的就是Dog.class)
难怪 ... 明白了 ! 可以结贴了 ... .................
lcf 2013-07-09
  • 打赏
  • 举报
回复
引用 26 楼 weidu23 的回复:
[quote=引用 16 楼 lcf 的回复:] [quote=引用 15 楼 lcf 的回复:] 生产环境中常用的一个插件是log4j,其中获得一个Logger的方式是LoggerFactory.getLogger(Class<?>),参数中填的要么是SomeClass.class,要么是getClass()。我可以这么写代码:
Abstract class Animal {
  protected Logger logger = LoggerFacotry.getLogger(getClass());
  ...
}
Cat extends Animal {
  Cat () {
  }
}
泥煤,不小心按ctrl+enter被发出去,然后又不能改贴。 这个Class中的logger可以被每个子类共用,而不需要每个子类都写一句LoggerFactory.getLogger(SomeClass.class);因为getClass是一个可复写的方法。这提供了灵活性[/quote] 这一句很是霸气,我仿佛看到了框架 ... 虽说是初学很浅,但是我记得框架里面,就是你现在上面这个道理。好像看到过 ... ------------ 不过,你这里可以被子类共用这句话说的有点抽象了,不是每个子类都要LoggerFactory.getLogger(SomeClass.class);么,不然怎么调用[好吧我真是菜鸟战斗机 ... ][/quote] Cat的目标是有一个Logger,它产生的过程等同于LoggerFactory.getLogger(Cat.class);。在Animal这个抽象类里面,那一句getClass是根据你实例化的子类来返回不同值的。比如你有Dog extends Animal { },那么new Dog()中的logger就相当于LoggerFactory.getLogger(Dog.class);,而你在Dog类中不需要重复写这一句,因为Animal类中,logger已经被初始化为这个值了(getClass()返回的就是Dog.class)
weidu23 2013-07-09
  • 打赏
  • 举报
回复
引用 16 楼 lcf 的回复:
[quote=引用 15 楼 lcf 的回复:] 生产环境中常用的一个插件是log4j,其中获得一个Logger的方式是LoggerFactory.getLogger(Class<?>),参数中填的要么是SomeClass.class,要么是getClass()。我可以这么写代码:
Abstract class Animal {
  protected Logger logger = LoggerFacotry.getLogger(getClass());
  ...
}
Cat extends Animal {
  Cat () {
  }
}
泥煤,不小心按ctrl+enter被发出去,然后又不能改贴。 这个Class中的logger可以被每个子类共用,而不需要每个子类都写一句LoggerFactory.getLogger(SomeClass.class);因为getClass是一个可复写的方法。这提供了灵活性[/quote] 这一句很是霸气,我仿佛看到了框架 ... 虽说是初学很浅,但是我记得框架里面,就是你现在上面这个道理。好像看到过 ... ------------ 不过,你这里可以被子类共用这句话说的有点抽象了,不是每个子类都要LoggerFactory.getLogger(SomeClass.class);么,不然怎么调用[好吧我真是菜鸟战斗机 ... ]
「已注销」 2013-07-08
  • 打赏
  • 举报
回复
我也觉得能用getClass()就用,不能用的时候就.class。
oh_Maxy 2013-07-08
  • 打赏
  • 举报
回复
11L讲的很实在~
lcf 2013-07-08
  • 打赏
  • 举报
回复
引用 15 楼 lcf 的回复:
生产环境中常用的一个插件是log4j,其中获得一个Logger的方式是LoggerFactory.getLogger(Class<?>),参数中填的要么是SomeClass.class,要么是getClass()。我可以这么写代码:
Abstract class Animal {
  protected Logger logger = LoggerFacotry.getLogger(getClass());
  ...
}
Cat extends Animal {
  Cat () {
  }
}
泥煤,不小心按ctrl+enter被发出去,然后又不能改贴。 这个Class中的logger可以被每个子类共用,而不需要每个子类都写一句LoggerFactory.getLogger(SomeClass.class);因为getClass是一个可复写的方法。这提供了灵活性
lcf 2013-07-08
  • 打赏
  • 举报
回复
生产环境中常用的一个插件是log4j,其中获得一个Logger的方式是LoggerFactory.getLogger(Class<?>),参数中填的要么是SomeClass.class,要么是getClass()。我可以这么写代码:
Abstract class Animal {
  protected Logger logger = LoggerFacotry.getLogger(getClass());
  ...
}
Cat extends Animal {
  Cat () {
  }
}
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 12 楼 lcf 的回复:
interface IAnimal {
  String whoAmI();
}

class Cat implements IAnimal {
 .........
}
读完代码你就懂了。这是两种应用场景
你的代码看完了 。 我鸡蛋里挑下骨头:你的代码是区分了两种方式的用法,这个我倒是会。我想说的是,如何区分为什么一定要这两种,或者说,在什么情况下非得用某种这两种方法中的一种 ... 抑或说,我想知道这方面编程的思想 ... 思想 ...
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 12 楼 lcf 的回复:
interface IAnimal {
  String whoAmI();
}

class Cat implements IAnimal {
 .........
}
读完代码你就懂了。这是两种应用场景
你的代码看完了 。 我鸡蛋里挑下骨头:你的代码是区分了两种方式的用法,这个我倒是会。我想说的是,如何区分为什么一定要这两种,或者说,在什么情况下非得用某种这两种方法中的一种 ... 抑或说,我想知道这方面变成的思想 ...
lcf 2013-07-08
  • 打赏
  • 举报
回复
引用 8 楼 weidu23 的回复:
[quote=引用 3 楼 lcf 的回复:] SomeClass.class,这个class是一个静态常量,返回值等于getClass的值。getClass是一个普通的成员函数,并不是静态函数。如果你不懂什么是静态函数,建议你先看更基础的东西再研究这个。 native表示该方法的实现通过调用JVM之外的代码来实现,通常是C/C++程序库,在Windows里面就是那些dll;也有可能是利用了JVM本身支持的功能,如System.arraycopy,以及这个getClass。native与否和静态与否没有必然联系,不要被误导。 下一个问题如果是为什么需要getClass和.class两种方法来获得对SomeClass的类引用,这就要牵涉到继承和多态。有兴趣的话就先搞清楚这两个概念再回帖吧
静态块还是理解的 ... 继承和多态是用得比较多,我知道 ... 现在的问题在于,getClass和.class两种方法来获得对SomeClass的类到底是为什么 ?[/quote]
interface IAnimal {
  String whoAmI();
}

class Cat implements IAnimal {
  @Override
  public String whoAmI() {
    return "I am " + Cat.class;
  }
}

class Dog implements IAnimal {
  @Override
  public String whoAmI() {
    return "I am " + Dog.class;
  }
}

class AnimalTest {
  public static void main (final String[] args) {
    IAnimal animal1 = new Cat();
    IAnimal animal2 = new Dog();

    tellMeWho(animal1);
    tellMeWho(animal2);

    System.out.println(animal1.whoAmI());
    System.out.println(animal2.whoAmI());
  }

  private static void tellMeWho(IAnimal animal) {
    System.out.println("I am " + animal.getClass());
  }
}
读完代码你就懂了。这是两种应用场景
逍遥jc 2013-07-08
  • 打赏
  • 举报
回复
静态的你就理解为是类的,非静态的你就理解为是对象的。对象可以访问类的方法(但不建议),但是类不能访问对象的方法。
北吹 2013-07-08
  • 打赏
  • 举报
回复
引用 9 楼 weidu23 的回复:
[quote=引用 5 楼 beichui 的回复:] 没那么复杂,一个是通过类找到class对象,一个是通过类的实例对象找到class对象,功能是一样,但是应对的场景不一样。
恩,那么我好奇的就在于,分别是用在哪种场景呢?[/quote] 你能确定类路径但是拿不到这个类的对象,就用.class,你能拿到对象,就用getClass()方法。
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 6 楼 bao110908 的回复:
MyClass.class 这个“class”字段是编译器在编译 MyClass 类时,自动加上去的,这个“class”是静态的、不可变的! 而 MyClass.getClass() 会产生编译错误,因为 getClass() 方法不是静态的,而是对象级别的,需要由 MyClass 的对象才可以进行调用 .............
你的回答很棒,不过,我想知道,为什么一定要两个不同的,总有原因吧,或说项目时特定情况下非得要某个吧?我想知道的,或说这个帖子,问的就是这个 ...
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 5 楼 beichui 的回复:
没那么复杂,一个是通过类找到class对象,一个是通过类的实例对象找到class对象,功能是一样,但是应对的场景不一样。
恩,那么我好奇的就在于,分别是用在哪种场景呢?
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 3 楼 lcf 的回复:
SomeClass.class,这个class是一个静态常量,返回值等于getClass的值。getClass是一个普通的成员函数,并不是静态函数。如果你不懂什么是静态函数,建议你先看更基础的东西再研究这个。 native表示该方法的实现通过调用JVM之外的代码来实现,通常是C/C++程序库,在Windows里面就是那些dll;也有可能是利用了JVM本身支持的功能,如System.arraycopy,以及这个getClass。native与否和静态与否没有必然联系,不要被误导。 下一个问题如果是为什么需要getClass和.class两种方法来获得对SomeClass的类引用,这就要牵涉到继承和多态。有兴趣的话就先搞清楚这两个概念再回帖吧
静态块还是理解的 ... 继承和多态是用得比较多,我知道 ... 现在的问题在于,getClass和.class两种方法来获得对SomeClass的类到底是为什么 ?
oh_Maxy 2013-07-08
  • 打赏
  • 举报
回复
引用 23 楼 weidu23 的回复:
[quote=引用 17 楼 oh_Maxy 的回复:] 11L讲的很实在~
CSDN兄弟,我们又见面了,哈哈 ... [/quote] 是啊,嘿嘿~
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 17 楼 oh_Maxy 的回复:
11L讲的很实在~
CSDN兄弟,我们又见面了,哈哈 ...
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 20 楼 cowfishy 的回复:
深层次来讲,Java虚拟机加载每个类的时候, 每个类不论它有多少对象,那个类和它的对象都共享了1份Class --> 共享不正是Java里面的static么 但是每个对象都有1个自己专属的ClassLoader .class属性是供类来访问的 getClass()是供对象来访问的 同时Class.forName(“包.类名称”)也是一种访问Class的方法 Java提供了这三种访问Class的方式
讲的透彻 !!!
weidu23 2013-07-08
  • 打赏
  • 举报
回复
引用 11 楼 beichui 的回复:
[quote=引用 9 楼 weidu23 的回复:] [quote=引用 5 楼 beichui 的回复:] 没那么复杂,一个是通过类找到class对象,一个是通过类的实例对象找到class对象,功能是一样,但是应对的场景不一样。
恩,那么我好奇的就在于,分别是用在哪种场景呢?[/quote] 你能确定类路径但是拿不到这个类的对象,就用.class,你能拿到对象,就用getClass()方法。[/quote] 完全明白了 !!!
加载更多回复(9)

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧