1

I have two classes under the same package.
Class A has a private hashmap _books = new ConcurrentHashMap<String,Book>(); String title is the key.
In class B, I would like to retrieve a certain Book object by its title from the private map in class A.

I tried to add a public method in class A

public Book getBookFromMap(String title ){
    return _books.get(title);
} 

And in class B I tried to call the method, but that didn't work. Eclipse says "the method getBookFromMap is undefined". In class I tried to do this:

Book bookFromMap= getBookFromMap(booktitle);

That's when the red line appeared under the getBookFromMap in class B. I reckon that maybe I'm not calling it correctly? How can I solve the problem? Many thanks in advance!

user3735871
  • 527
  • 2
  • 14
  • 31
  • @user3735871 what method is undefined? – Jacek Cz Sep 09 '15 at 08:52
  • Please show the full code and stack trace. – BetaRide Sep 09 '15 at 08:54
  • 1
    @Tunaki he clearly said he added the method do class A which holds the private map. This should work. – lschuetze Sep 09 '15 at 08:54
  • How did you call the method? Can you post the method call code here? – Codebender Sep 09 '15 at 08:54
  • You said that you tried calling public method in A. I cannot see how it could not work. Could you please post your entire code? – Jaroslaw Pawlak Sep 09 '15 at 08:54
  • "the method is undefined" can show how you are calling `getBookFromMap` method. – Subir Kumar Sao Sep 09 '15 at 08:55
  • @Tunaki maybe not protected, but "package" aka "default" access level (without private, protected, or public. In general: this way is poor in OOP sense – Jacek Cz Sep 09 '15 at 08:55
  • just clean and build the project. if that doesn't work show us how u called `getBookFromMap` from `B class` (also check that u type it correctly :) ) – nafas Sep 09 '15 at 08:57
  • Thanks guys! @nafas I have edited my question. I think maybe I'm not calling the method in class A correctly? Forgive me if the mistake is too obvious.. I am quite new to this. – user3735871 Sep 09 '15 at 09:05
  • @user3735871 mate, its a simple mistake, jacek just posted something that will help u (just give him few min to put some explaination) – nafas Sep 09 '15 at 09:07

5 Answers5

2
Book bookFromMap= aObjectOfClassA.getBookFromMap(booktitle);
Jacek Cz
  • 1,872
  • 1
  • 15
  • 22
  • My class A only contains methods that handles incoming http request. I am working with JAX-RS. How can I have a object of class in this case? – user3735871 Sep 09 '15 at 09:08
  • My Class A is like this `public class StoreImpl { @POST @Consumes("application/xml") Response createBook( Book book );...}` I am not sure how to get a object of this class – user3735871 Sep 09 '15 at 09:11
  • problem with instance.method() is very simply, basic to Java. I can't help You on small spinets of code with webservices. – Jacek Cz Sep 09 '15 at 09:18
2

you can't directly access a method that is defined in another class.

what you need to do is to initialize an instance of class A using its constructor for Example:

A myInstance = new A();

then you will be able to access the method inside class A by using

Book myBook = myInstance.getBookFromMap(booktitle);

An Alternative solution

By using static : its normally preferable not to use static, but in this case, its probably easier approach. (try to avoid static as much as you can, but use it as necessary)

so you need to define shared things as static:

in A class you'll have :

private static hashmap _books = new ConcurrentHashMap<String,Book>();


public static Book getBookFromMap(String title ){
    return _books.get(title);
} 

and in B class :

Book bookFromMap= A.getBookFromMap(booktitle); //accessing getBookFromMap method in class A
nafas
  • 5,283
  • 3
  • 29
  • 57
  • Thanks! I see where the problem is. But My Class A only contains methods that handle incoming http request, the class is like this `public class StoreImpl { @POST @Consumes("application/xml") Response createBook( Book book );...} `I am not sure how to get a object of this class in this case. I mean I dont want to have a new class A every time. – user3735871 Sep 09 '15 at 09:14
  • 1
    @user3735871 I just edited the answer to how you can call the method without creating an instance . – nafas Sep 09 '15 at 09:16
  • @nafas wrapping a static method round a `Map` seems totally pointless in absence of anything else other than a `get` – Nick Holt Sep 09 '15 at 09:22
  • @NickHolt on the solution I couldn't specify more not to use `static`, but its a quick and dirty solution. beside it create simplicity – nafas Sep 09 '15 at 09:27
  • @nafas imho, for the calling code to do a `map.get` is simpler that `A.get` which then invokes `map.get` – Nick Holt Sep 09 '15 at 10:45
  • @NickHolt, that's true , but at the same it could count as a security measures to ensure that no external class (apart from `A` itself) can modify the Map. then again its entirely depends on the design specification – nafas Sep 09 '15 at 11:00
1

You can use Java reflections API, but it's not recommended in most cases. Here's example

  • 2
    Dont use reflection, here is simple error or un-understanding of coding. Like shooting from cannon to sparrow. But You said (in generally) trye, reflection in some cases can have access to "private". So upwote on this answer is wrong. I give down – Jacek Cz Sep 09 '15 at 09:00
1

You need to create an instance of class A and reference its getBookFromMap via that instance.

This is what class A should look like:

public class A
{
  private Map<String, Book> booksByTitle;

  public A(Book... books)
  {
    this.booksByTitle = new ConcurrentHashMap<>();

    for (Book book : books)
    {
      this.booksByTitle.put(book.getTitle(), book);
    }
  }

  public Book getBookForTitle(String title) throws BookNotFoundException
  {
    Book book = booksByTitle.get(title);

    if (book == null)
    {
      throw new BookNotFoundException("Book not found for title: " + title);
    }

    return book;
  }
}

While the tests might look like this:

@Test
public void testGetBookForTitle() throws Exception
{
  Book warAndPeace = new Book("War & Peace")

  A a = new A(warAndPeace);

  assertEquals(warAndPeace, a.getBookForTitle(warAndPeace.getTitle));
}

@Test(expected = BookNotFoundException.class)    
public void testGetBookForInvalidTitle() throws Exception
{
  A a = new A();
  a.getBookForTitle("invalid");
}
Nick Holt
  • 33,455
  • 4
  • 52
  • 58
0

Change _books to

ConcurrentHashMap<String,Book> _books;

(just remove the private at the start of the line).

Or use reflection to access the field, see How do I read a private field in Java?

Community
  • 1
  • 1
BetaRide
  • 16,207
  • 29
  • 99
  • 177