天道酬勤,学无止境

Object vs String Method [duplicate]

Possible Duplicate:
Overloaded method selection based on the parameter’s real type
How is an overloaded method choosen when a parameter is the literal null value?

When I execute the code below, I get the following output:

Method with String argument Called ..."

Why?

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test(null);
    }
}
标签

评论

The null in the call matches both the test() signatures. You have to cast the null to ensure it calls one or the other.

A similar example is from Java Puzzles if I recall correctly.

null can be of String type or Object type. But the JVM will always choose a more accurate method.

In this case, String is more accurate then Object. (a String is an Object, but an Object might not be a String).

It is not a good habit to write code like this. Try to cast parameters to match your desired method, like

public class StringObjectPOC {

    public static void test(Object o)   {
        System.out.println("Method with Object argument Called ...");
    }
    public static void test(String str){
        System.out.println("Method with String argument Called ...");
    }
    public static void main(String[] args) {
        StringObjectPOC.test((Object)null);
    }
}

I tried this:

Test2.class

public class Test2{}

Test3.class

public class Test3 extends Test2{

}

Test.class

public class Test{

public static void print(Object obj){
    System.out.println("Object");
}

public static void print(Test2 obj){
    System.out.println("test 2");
}

public static void print(Test3 obj){
    System.out.println("Test 3");
}


public static void main(String[]args){
    Test.print(null);
}

}

it printed out Test 3

Just like in your scenario, this means that if a method is overloaded (and when null is passed), it recognizes the method which has the child-most parameter.

Object->Test->Test2

or in your case:

Object->String

Java tries to find the most specific method possible to call. String is a subclass of object, so Java will defer to the String method whenever it can. null is a perfectly acceptable value for either an Object or a String, but since a String is more specific than an Object, Java defers to the String method because it is more precise.

null is could be both a String and/or an Object but because String inherits from Object, it will try to use the signature that is more precise. You can cast null to choose which method to execute:

public static void main(String[] args) {
    Test.test((Object) null); // treats as Object
    Test.test((String) null); // treats as String
    Test.test(null);          // treats as String
}

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • JS字符串“ +”与concat方法[重复](JS strings “+” vs concat method [duplicate])
    问题 这个问题已经在这里有了答案: 连接JavaScript中字符串的最有效方法? (6个答案) 5年前关闭。 我对Java有一定的经验,我知道用“ +”运算符连接的字符串会产生新的对象。 我想知道如何以最佳方式在JS中进行操作,最佳做法是什么? 回答1 MDN关于string.concat()有以下说法: 出于性能原因,强烈建议使用字符串连接运算符(+,+ =)代替此方法 另请参阅@Bergi的链接。 回答2 在JS中,“ +”串联通过创建新的String对象来起作用。 例如,使用... var s = "Hello"; ...我们有一个对象s 。 下一个: s = s + " World"; 现在, s是一个新对象。 第二种方法:String.prototype.concat 回答3 曾经有一段时间,将字符串添加到数组中并使用join最终确定字符串是最快/最好的方法。 如今,浏览器具有高度优化的字符串例程,建议+和+=方法最快/最好 回答4 我们不能使用concat()函数将字符串变量连接为整数变量,因为此函数仅适用于字符串,不适用于整数。 但是我们可以使用+运算符将字符串连接为数字(整数)。 众所周知,功能比运算符要慢得多。 函数需要将值传递给预定义的函数,并且需要收集函数的结果。 这比使用运算符进行运算要慢,因为运算符可以直接执行运算,但是函数会跳转到适当的内存位置
  • HashSet vs TreeSet vs LinkedHashSet在添加重复值的基础上(HashSet vs TreeSet vs LinkedHashSet on basis of adding duplicate value)
    问题 我正在学习核心Java的心脏,即Collections 。 我想知道当我们在HashSet , TreeSet , LinkedHashSet添加重复元素时内部会发生什么。 无论条目被替换,忽略还是引发异常,程序都将终止。 一个子问题是,哪个问题的所有操作都具有相同或平均的时间复杂度 您的答复将不胜感激。 回答1 Java中的TreeSet,LinkedHashSet和HashSet是集合框架中的三个Set实现,并且像许多其他设置一样,它们也用于存储对象。 TreeSet的主要功能是排序,LinkedHashSet是插入顺序,HashSet只是用于存储对象的通用集合。 HashSet是使用Java中的HashMap实现的,而TreeSet是使用TreeMap实现的。 TreeSet是一个SortedSet实现,它允许它按Comparable或Comparator接口定义的排序顺序保留元素。 Comparable用于自然顺序排序,而Comparator用于对象的自定义顺序排序,可在创建TreeSet实例时提供。 无论如何,在看到TreeSet,LinkedHashSet和HashSet之间的区别之前,让我们看一下它们之间的一些相似之处: 1)重复项:这三个工具都有Set接口,这意味着它们不允许存储重复项。 2)线程安全性:HashSet
  • Factory Method Vs Abstract Factory [duplicate]
    This question already has answers here: What are the differences between Abstract Factory and Factory design patterns? (21 answers) Closed 7 years ago. I have read about Factory Method where Sub class creates needed Object and Abstract Factory has methods where concrete classes creates needed Object Factory Method public class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); } abstract Pizza createPizza(String type); } public NewYorkPizzaStore extends PizzaStore { public Pizza createPizza(String type) { Pizza pizza
  • 工厂方法与抽象工厂 [重复](Factory Method Vs Abstract Factory [duplicate])
    问题 这个问题在这里已经有了答案: 抽象工厂和工厂设计模式有什么区别? (21 个回答) 7年前关闭。 我已经阅读了工厂方法,其中子类创建所需的对象,而抽象工厂具有具体类创建所需对象的方法 工厂方法 public class PizzaStore { public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); } abstract Pizza createPizza(String type); } public NewYorkPizzaStore extends PizzaStore { public Pizza createPizza(String type) { Pizza pizza = null; if("cheese".equals(type)) { pizza = new CheesePizza(); } else if("onion".equals(type)) { pizza = new OnionPizza(); } return pizza; } } public class pizzaTestDriveByFactoryMethod() { public static void main
  • string.replace vs StringBuilder.replace 内存[重复](string.replace vs StringBuilder.replace for memory [duplicate])
    问题 这个问题在这里已经有了答案: String.Replace() 与 StringBuilder.Replace() 9 个答案 8年前关闭。 我已经下载了一个大约 36MB 的 byte[] 'raw' 流。 然后我将其转换为字符串 string temp = System.Text.Encoding.UTF8.GetString(raw) 然后我需要用“\r\n”替换所有“\n”所以我尝试了 string temp2 = temp.Replace("\n","\r\n") 但它引发了“内存不足”异常。 然后我尝试使用 StringBuilder 创建一个新字符串: string temp2 = new StringBuilder(temp).Replace("\n","\r\n").toString() 它没有抛出异常。 为什么首先会出现内存问题(我在这里只处理 36MB),而且为什么 StringBuilder.Replace() 在另一个不工作时工作? 回答1 当您使用: string temp2 = temp.Replace("\n","\r\n") 对于字符串 temp 中的每个匹配 "\n",系统都会创建一个带有替换的新字符串。 使用 StringBuilder 不会发生这种情况,因为 StringBuilder 是可变的
  • String.valueOf(someVar) vs ("" + someVar) [重复](String.valueOf(someVar) vs ("" + someVar) [duplicate])
    问题 这个问题在这里已经有了答案: String valueOf 与空字符串的连接(10 个回答) 4年前关闭。 我想知道两种方法的区别。 我现在正在处理一些旧代码,它们通过连接空字符串""将primitive值设置为String值。 obj.setSomeString("" + primitiveVariable); 但是在这个链接 Size of empty Java String 它说如果你为每个实例创建一个单独的空字符串,那么显然这将占用更多内存。 所以我想到在String类中使用valueOf方法。 我检查了文档 String.valueOf() 它说如果参数为空,则字符串等于“null”; 否则,返回 obj.toString() 的值。 那么哪一个是更好的方法 obj.setSomeString("" + primitiveVariable); obj.setSomeString(String.valueOf(primitiveVariable)); 上述过程是在一个大小超过 600 的List迭代中完成的,并且预计将来会增加。 回答1 当您执行"" ,不会创建对象。 它将创建一个字符串文字。 实际上有一个差异(如何使用“”初始化字符串?)。 来到你的实际问题, 来自字符串连接文档 Java 语言为字符串连接运算符 ( + ) 以及将其他对象转换为字符串提供了特殊支持
  • 为什么字符串连接需要这么长时间? [复制](Why string concatenation takes so long time? [duplicate])
    问题 这个问题在这里已经有了答案: Java 中 toString() 中的 StringBuilder 与字符串连接(19 个回答) 6年前关闭。 我在一个循环中连接一个字符串,但它需要很长时间,这是为什么? for (String object : jsonData) { counter++; finalJsonDataStr += object; } 变量object是一段 JSON,最多 70 个字符,循环大约 50k 次。 我理解有些人建议StringBuffer或StringBuilder但这个链接说,它没有性能改进:StringBuilder vs String concatenation in toString() in Java 回答1 使用字符串生成器附加到字符串。 当您连接时,Java 实际上是用连接的结果创建一个新的 String。 多次这样做,你就会白白创造无数的字符串。 尝试: StringBuilder sb = new StringBuilder(); for (String object : jsonData) { counter++; sb.append(object.toString()); //this does the concatenation internally //but is very efficient }
  • SqlCommand参数添加vs.AddWithValue [重复](SqlCommand Parameters Add vs. AddWithValue [duplicate])
    问题 这个问题已经在这里有了答案: 与Parameters.Add和Parameters.AddWithValue的区别(4个答案) 7年前关闭。 什么时候应该使用Parameters. Add/AddWithValue Parameters. Add/AddWithValue ? 在下面的MSDN示例中,他们将Parameters.Add用于int并将Parameters.AddWithValue用于string command.Parameters.Add("@ID", SqlDbType.Int); command.Parameters["@ID"].Value = customerID; command.Parameters.AddWithValue("@demographics", demoXml); 什么是datetime的最佳选择 回答1 如果您想使所有内容变得更加明确,请使用Add 。 如果您很懒,请使用AddWithValue 。 AddWithValue将派生其值的参数类型,因此请确保它是正确的类型。 例如,如果string是正确的类型,则应将其解析为int 。 有一个避免使用Add原因:如果您的参数类型为int ,则必须小心采用参数名和对象的重载,因为然后使用SqlDbType-enum选择了另一个重载。 从评论(方法过载现在obsolete了):
  • {} - 0 VS ({} - 0) 在 JavaScript [重复]({} - 0 VS ({} - 0) in JavaScript [duplicate])
    问题 这个问题在这里已经有了答案: CodeMash 2012 的“Wat”演讲中提到的这些奇怪的 JavaScript 行为的解释是什么? (5 个回答) 为什么 {}+[] 与 ({}+[]) 不同? [重复] (1 个回答) 3年前关闭。 在 Chrome JavaScript 控制台中,为什么将语句{} - 0括在括号中会更改返回值? {} - 0 // Returns -0 ({} - 0) // Returns NaN 将单个语句括在括号中会改变包含的值,这似乎非常奇怪。 我在这里缺少什么? 回答1 {} - 0行有两种可能的解释: 可以解释为{}; -0 {}; -0 ,其中{}被解释为空块语句, -是一元否定运算符(因此-0只是“负零”)。 评估时 this 的值是最后一条语句的值,即 -0。 它可以解释为({} - 0) ,其中{}被解释为一个空对象,并且-是减法运算符(因此从{}减去0 )。 在您的第一行中,这是模棱两可的,因此它将选择第一种解释。 在第二行中,第一个解释是无效的(因为块语句永远不能成为表达式的一部分,你用括号强制它)。 回答2 {} - 0 :这里的{}只是一个什么都不做的空块,所以-0由控制台返回。 ({} - 0) :这里的{}是表达式的一部分并被转换为数字。 在该空对象中没有定义valueOf()方法,并且在转换为数字时
  • .nil?、.blank 之间的区别? 和.空? [复制](Difference between .nil?, .blank? and .empty? [duplicate])
    问题 这个问题在这里已经有了答案: 8年前关闭。 可能重复: Ruby on Rails 中 nil v. empty v. blank 的简明解释 谁能告诉我nil?之间的区别nil? , blank? 和empty? 在红宝石? 回答1 在 Ruby 中,对象中的nil (类NilClass的单个实例)。 这意味着可以对其调用方法。 nil? 是 Ruby 中的标准方法,可以在所有对象上调用,并为nil对象返回true ,为其他任何对象返回false 。 empty? 是一些对象(如数组、哈希和字符串)上的标准 Ruby 方法。 它的确切行为将取决于特定对象,但如果对象不包含任何元素,它通常返回true 。 blank? 不是标准的 Ruby 方法,而是由 Rails 添加到所有对象,并为nil 、 false 、 empty 或空白字符串返回true 。 因为empty? 不是为所有对象定义的,如果你调用empty?你会得到一个NoMethodError empty? 在nil以避免必须编写诸如if x.nil? || x.empty? if x.nil? || x.empty? Rails 添加了blank? 方法。 在回答之后,我发现了一个较早的问题,“如何理解 Rails(和 Ruby)中的 nil 与空与空白”,所以你也应该检查一下答案。 回答2 感受一下;) 零?
  • 引用类型与值类型 [重复](Reference type vs value type [duplicate])
    问题 这个问题在这里已经有了答案: C# 字符串引用类型? (11 个回答) 7年前关闭。 我正在阅读 C# 中的结构和类,据我所知,结构是值类型,类是引用类型。 但是我对类对象作为参数传递给方法时的行为方式感到有些困惑。 假设我有以下代码: public class Program { public static void Main(string[] args) { var program = new Program(); var person = new Person { Firstname = "Bob", }; Console.WriteLine(person.Firstname); program.ChangeName(person); Console.WriteLine(person.Firstname); program.Kill(person); Console.WriteLine(person.Firstname); Console.Read(); } public void ChangeName(Person p) { p.Firstname = "Alice"; } public void Kill(Person p) { p = null; } } 当我通过我的实例Person类Program.ChangeName()和改变的值person
  • Java中的字符串:等于vs == [重复](Strings in Java : equals vs == [duplicate])
    问题 这个问题已经在这里有了答案: 8年前关闭。 可能重复: 如何比较Java中的字符串? String s1 = "andrei"; String s2 = "andrei"; String s3 = s2.toString(); System.out.println((s1==s2) + " " + (s2==s3)); 给出以下代码,为什么第二个比较s2 == s3为true? s2.toString()返回的实际上是什么? 实际位于哪里(s2.toString()) ? 回答1 首先, String.toString是no-op: /** * This object (which is already a string!) is itself returned. * * @return the string itself. */ public String toString() { return this; } 其次,对String常量进行了插值,因此s1和s2在幕后被更改为相同的String实例。 回答2 方法String.intern()可用于确保相等的字符串具有相等的引用。 字符串常量是内部intern ,因此s1和s2将引用相同的字符串。 String.toString()仅返回自身,即,当a为String时, a.toString()返回a。 因此,s2也==
  • C#as强制转换与经典强制转换(C# “as” cast vs classic cast [duplicate])
    问题 这个问题已经在这里有了答案: 8年前关闭。 可能重复: 在CLR中投放与使用'as'关键字 我最近了解了一种不同的投射方式。 而不是使用 SomeClass someObject = (SomeClass) obj; 可以使用以下语法: SomeClass someObject = obj as SomeClass; 如果obj不是SomeClass,则似乎返回null,而不是引发类强制转换异常。 我看到如果强制转换失败并且我尝试访问someObject变量,则可能导致NullReferenceException。 所以我想知道这种方法的原理是什么? 为什么要使用这种转换方式而不是(旧的)转换方式-似乎只能将失败的“更深层”转换问题转移到代码中。 回答1 使用“经典”方法,如果强制转换失败,则会引发InvalidCastException。 使用as方法,它将导致null ,可以对其进行检查,并避免引发异常。 此外,您只能将as与引用类型一起使用,因此,如果将类型转换为值类型,则仍必须使用“经典”方法。 笔记: as方法只能用于可以分配null值的类型。 该用法仅表示引用类型,但是当.NET 2.0出现时,它引入了可为空的值类型的概念。 由于可以为这些类型分配null值,因此可以与as运算符一起使用。 回答2 空比较远快于抛出和捕获异常。 异常会产生大量开”
  • Integer.valueOf()与Integer.parseInt()[重复](Integer.valueOf() vs. Integer.parseInt() [duplicate])
    问题 这个问题已经在这里有了答案: java中parseInt()和valueOf()之间的区别? (11个答案) 3年前关闭。 除了处理负号的Integer.parseInt() (如所记录)外, Integer.valueOf()和Integer.parseInt()之间还有其他区别吗? 而且由于两者都无法解析,因此小数千位分隔符(产生NumberFormatException ),是否已经有可用的Java方法来做到这一点? 回答1 实际上, valueOf内部使用parseInt 。 区别在于parseInt返回一个int原语,而valueOf返回一个Integer对象。 从Integer.class来源考虑: public static int parseInt(String s) throws NumberFormatException { return parseInt(s, 10); } public static Integer valueOf(String s, int radix) throws NumberFormatException { return Integer.valueOf(parseInt(s, radix)); } public static Integer valueOf(String s) throws
  • 与JavaScript中的exec匹配(match Vs exec in JavaScript [duplicate])
    问题 这个问题已经在这里有了答案: RegExp的exec()函数和String的match()函数之间有什么区别? (6个答案) 3年前关闭。 我需要对JavaScript中的Match Vs exec进行一些说明; 这里有人说 “带有全局正则表达式的exec打算在循环中使用”,但首先,正如您在我的示例中看到的那样,情况并非如此; 在我的示例中,具有全局正则表达式的exec返回数组中的所有匹配项! 其次,他们说,对于String.match,它不需要循环就返回所有匹配项! 但是,在我的示例中再次没有发生这种情况,只是返回了输入字符串? 我是否误解/做错了什么? var myString = "[22].[44].[33]."; var myRegexp = /.*\[(\d*)*\].*\[(\d*)*\].*\[(\d*)*\].*/g; var execResult = myRegexp.exec(myString); console.log(execResult.length); console.log(execResult[1]);// returns 22 and execResult has all of my matches from index 1 to the length of array var matchResult = myString.match
  • + =新的EventHandler(Method)与+ =方法[重复](+= new EventHandler(Method) vs += Method [duplicate])
    问题 这个问题已经在这里有了答案: 8年前关闭。 可能重复: C#:“ + = anEvent”和“ + = new EventHandler(anEvent)”之间的区别 订阅事件有两种基本方法: SomeEvent += new EventHandler<ArgType> (MyHandlerMethod); SomeEvent += MyHandlerMethod; 有什么区别,何时应选择一个? 编辑:如果相同,那么为什么VS默认为长版本,从而使代码混乱? 这对我完全没有意义。 回答1 由于我的原始答案似乎有些争议,因此我决定进行一些测试,包括查看生成的代码和监视性能。 首先,这是我们的测试平台,一个带有委托的类和另一个使用它的类: class EventProducer { public void Raise() { var handler = EventRaised; if (handler != null) handler(this, EventArgs.Empty); } public event EventHandler EventRaised; } class Counter { long count = 0; EventProducer producer = new EventProducer(); public void Count() { producer
  • 什么时候使用 nil、blank、empty? [复制](When to use nil, blank, empty? [duplicate])
    问题 这个问题在这里已经有了答案: 如何理解 Ruby 中的 nil 与空与空白(15 个回答) 5年前关闭。 是否有关于如何区分.nil? , .blank? 和. .empty? ? 我通常总是对何时在我的应用程序中使用它们感到困惑,因为它们似乎都意味着相同的事情但具有不同的含义。 有人有关于血腥细节的备忘单吗? 回答1 零? - 检查变量是否正在引用一个对象empty? - 可用于检查各种对象类型,如空字符串 "" 或空数组 [] 空白的? - 检查nil? 还是empty? . 回答2 在这里,我用所有案例制作了这张有用的表格 回答3 nil? 在所有Objects上定义,它只在nil单例上返回true 。 blank? 也定义在所有对象上,如果对象也响应empty? ,则返回true empty? and 是空的,或者是一个false类型值( !object总是true )。 empty? 在多个集合对象上定义,如果没有元素则为true 。 它也在String定义。 注意那个blank? 是ActiveSupport而不是Rails 1.8 。 回答4 我在这里找到了一个很好的解释: 零? 测试对象是否完全为零,即它是否是 NilClass 的唯一想要的实例。 空的? 是一些对象响应的方法。 您需要检查每个案例的文档。 例如,空数组是一个不为 nil 的数组(它是一个数组
  • 在Java中迭代数组的最快方法:循环变量vs语句增强[重复](Fastest way to iterate an Array in Java: loop variable vs enhanced for statement [duplicate])
    问题 这个问题已经在这里有了答案: for循环和for-each循环之间是否存在性能差异? (16个回答) 4年前关闭。 在Java中,以老式的方式遍历数组是否更快, for (int i = 0; i < a.length; i++) f(a[i]); 或者使用更简洁的形式, for (Foo foo : a) f(foo); 对于ArrayList,答案是否相同? 当然,对于大量的应用程序代码,答案是它没有明显的区别,因此应使用更简洁的形式以提高可读性。 但是,我正在研究的上下文是重型技术计算,必须执行数十亿次操作,因此即使很小的速度差异也可能会变得非常重要。 回答1 如果您要遍历数组,没关系-增强的for循环无论如何都会使用数组访问。 例如,考虑以下代码: public static void main(String[] args) { for (String x : args) { System.out.println(x); } } 当使用javap -c Test反编译时,我们得到(用于main方法): public static void main(java.lang.String[]); Code: 0: aload_0 1: astore_1 2: aload_1 3: arraylength 4: istore_2 5: iconst_0 6: istore_3
  • Abstract Factory vs Factory method: Composition vs Inheritance? [duplicate]
    This question already has answers here: Factory, Abstract Factory and Factory Method (3 answers) Closed 7 years ago. I have read a lot of posts about different between Abstract Factory and Factory method, but there are a problem I can't understand. One difference between the two is that with the Abstract Factory pattern, a class delegates the responsibility of object instantiation to another object via composition whereas the Factory Method pattern uses inheritance and relies on a subclass to handle the desired object instantiation Maybe I know why Abstract Factory pattern use composition and
  • ArrayList与Arrays.asList()返回的列表[重复](ArrayList vs the List returned by Arrays.asList() [duplicate])
    问题 这个问题已经在这里有了答案: 为什么Arrays.asList()返回其自己的ArrayList实现(6个答案) 6年前关闭。 该方法Arrays.asList(<T> ... A)返回的列表表示A 。 这里返回的对象是由数组支持的List,但不是ArrayList对象。 我正在寻找Arrays.asList()返回的对象与ArrayList对象之间的区别-一种快速的资源来告诉它们而无需深入研究代码。 TIA。 回答1 当您调用Arrays.asList时,它不会返回java.util.ArrayList 。 它返回一个java.util.Arrays$ArrayList ,它是由原始源数组支持的固定大小的列表。 换句话说,它是使用Java的基于集合的API公开的数组的视图。 String[] sourceArr = {"A", "B", "C"}; List<String> list = Arrays.asList(sourceArr); System.out.println(list); // [A, B, C] sourceArr[2] = ""; // changing source array changes the exposed view List System.out.println(list); //[A, B, ] list.set(0, "Z"); //