Skip to content

Instantly share code, notes, and snippets.

@amrza
Last active February 26, 2018 05:55
Show Gist options
  • Save amrza/a1d90ca887bccfba309699560cde551a to your computer and use it in GitHub Desktop.
Save amrza/a1d90ca887bccfba309699560cde551a to your computer and use it in GitHub Desktop.
Objects of the same type will have access to each others private and protected members even though they are not the same instances! WTF!
// Person.class
//-------------------------
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void changeName(Person p, String newName) {
p.name = newName; // the problem is here!
}
}
// App.class
//-------------------------
public class App {
public static void main(String[] args) {
// We create two Person!
Person john = new Person("John");
Person mary = new Person("Mary");
// Ok, its fine. it will print: John
System.out.println(john.getName());
// Ok, its fine. it will print: Mary
System.out.println(mary.getName());
// How this can happen when mary's name is private?
john.changeName(mary, "Susan");
// What the f*ck? how can john change mary's name?
System.out.println(mary.getName());
}
}
@ans-ashkan
Copy link

john.ChangeName(john, "my new name");

 public void changeName(Person p, String newName) {
        p.name = newName;  // look, p is john, this is john too. how can this be a problem
}

@intuxicated
Copy link

# ruby
class Person

  def initialize(name)
     @name = name
  end

  def printName
    print @name + "\n"
  end

  def assignName (person, name)
    person.name = name
  end

  private

  attr_accessor :name

end

john = Person.new('john')
mary = Person.new('mary')
john.printName
mary.printName
mary.assignName john, 'JOHN'
john.printName
person.rb:12:in `assignName': private method `name=' called for #<Person:0x00007fcfe114d648 @name="john"> (NoMethodError)
	from person.rb:25:in `<main>'

@amrza
Copy link
Author

amrza commented Feb 25, 2018

@intuxicated ruby is doing the correct job here.

@m3hdiii
Copy link

m3hdiii commented Feb 26, 2018

According to the Specification of java :
when a class variable access modifier defines as "private" this parameter is still accessible within the body of that class. Now look at this part :
p.name = newName; // the problem is here!
Since this p.name has been declared within the body of the Person class the rule of restriction isn't enforced.
Take a look at this link :
https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6.1

Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.

I'm agree that having the access modifier must be enforced within object-level not class-level BUT I'm pretty sure that there are other scenarios like encapsulating an "static inner class" for creating builder pattern will get affected by the means of this restriction so I do believe that the team of Java has come up with a right way of enforcement and productivity of the compiler design and after all they come up with this particular criteria.

Anyways Java still Rocks and this scenario is duplicating within lots of other modern and well-known programming languages now a days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment